앞서 BeautifulSoup를 이용하여 HTML 문서를 파싱하고 원하는 태그를 선택하는 방법을 알아봤다. 지금부터는 찾아낸 태그에서 텍스트를 추출하고 가공하는 방법을 정리해 보자.

BeautifulSoup은 태그 내부의 텍스트 콘텐츠를 나타내기 위해 NavigableString이라는 특별한 객체를 사용한다. NavigableString 객체는 마치 파이썬의 문자열처럼 다룰 수 있지만, BeautifulSoup의 일부 기능을 활용할 수 있다는 장점을 가지고 있다.

텍스트 콘텐츠 추출: string 속성과 get_text() 메서드

string 속성을 사용하면 태그에서 텍스트 콘텐츠를 쉽게 추출할 수 있다. string 속성은 태그 내부의 첫 번째 텍스트 콘텐츠를 NavigableString 객체로 반환한다. 만약 태그 내부에 여러 텍스트 콘텐츠가 존재하거나, 자식 태그가 포함되어 있는 경우에는 get_text() 메서드를 사용하면 된다. get_text() 메서드는 태그 내부의 모든 텍스트 콘텐츠를 하나의 문자열로 합쳐서 반환한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
html = """
<div>
<h1>오늘의 메뉴</h1>
<ul>
<li>김치찌개</li>
<li>된장찌개 <span class="price">7,000원</span></li>
</ul>
</div>
"""

soup = BeautifulSoup(html, 'lxml')

# h1 태그의 텍스트 콘텐츠 추출
title = soup.find('h1').string
print(title) # 출력: 오늘의 메뉴

# ul 태그의 모든 텍스트 콘텐츠 추출
menu_list = soup.find('ul').get_text()
print(menu_list) # 출력: 김치찌개\n된장찌개 7,000원

텍스트 콘텐츠 변경: string 속성과 replace_with() 메서드

NavigableString 객체는 변경 가능한 객체이기 때문에, 텍스트 콘텐츠를 직접 수정할 수 있다. string 속성을 사용하여 텍스트 콘텐츠를 새로운 문자열로 변경하거나, replace_with() 메서드를 사용하여 특정 텍스트를 다른 내용으로 바꿀 수 있다.

1
2
3
4
5
6
7
# h1 태그의 텍스트 콘텐츠 변경
soup.find('h1').string = "내일의 메뉴"
print(soup.find('h1').text) # 출력: 내일의 메뉴

# span 태그의 텍스트 콘텐츠 변경
soup.find('span').string.replace_with("8,000원")
print(soup.find('ul').get_text()) # 출력: 김치찌개\n된장찌개 8,000원

텍스트 데이터 정제: 불필요한 공백 및 특수 문자 제거

웹 페이지에서 추출한 텍스트 데이터에는 종종 불필요한 공백, 줄 바꿈, 특수 문자가 포함되어 있다. 이러한 불필요한 문자들은 텍스트 분석을 어렵게 만들 수 있으므로, 텍스트 데이터를 정제하는 과정이 필요하다.

strip(), lstrip(), rstrip(): 공백 제거

파이썬의 내장 함수인 strip(), lstrip(), rstrip() 메서드를 사용하여 문자열의 양쪽 끝, 왼쪽 끝, 오른쪽 끝에 있는 공백을 제거할 수 있다.

1
2
3
4
text = "   웹 스크래핑 \n\t "
print(text.strip()) # 출력: 웹 스크래핑
print(text.lstrip()) # 출력: 웹 스크래핑 \n\t
print(text.rstrip()) # 출력: 웹 스크래핑

replace(): 특정 문자열 바꾸기

replace() 메서드를 사용하여 특정 문자열을 다른 문자열로 바꿀 수 있다. 예를 들어, 텍스트 데이터에서 줄 바꿈 문자(\n)을 공백으로 바꾸려면 다음과 같이 하면 된다.

1
2
text = "웹 스크래핑\n\nBeautifulSoup"
print(text.replace('\n', ' ')) # 출력: 웹 스크래핑 BeautifulSoup

정규 표현식 활용: 복잡한 패턴 제거

정규 표현식은 복잡한 문자열 패턴을 찾고 조작하는 데 유용한 도구이다. 파이썬의 re 모듈을 사용하여 정규 표현식을 활용할 수 있다. 예를 들어, 텍스트 데이터에서 HTML 태그를 제거하려면 다음과 같이 할 수 있다.

1
2
3
4
5
import re

text = "<p>웹 스크래핑</p> <b>BeautifulSoup</b>"
clean_text = re.sub('<[^>]+>', '', text)
print(clean_text) # 출력: 웹 스크래핑 BeautifulSoup

정규 표현식: 특정 패턴의 텍스트 찾기

정규 표현식은 특정 패턴의 텍스트를 찾는 데에도 유용하게 활용될 수 있다. 예를 들어, 이메일 주소, 전화번호, 날짜 등의 특정 형식을 가진 텍스트를 찾아낼 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
import re

text = "제 이메일 주소는 example@example.com 입니다."

# 이메일 주소 패턴
email_pattern = r"([a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+)"

# 텍스트에서 이메일 주소 찾기
match = re.search(email_pattern, text)

if match:
print(match.group(1)) # 출력: example@example.com

마무리

이제는 웹 페이지를 스크래핑하는 실전으로 돌입할 때가 되었다.