BeautifulSoup(약칭 bs4)는 HTML 및 XML과 같은 초과 마크업 텍스트를 처리하고, 원하는 태그 내부의 텍스트를 추출하는 데 유용한 파이썬 라이브러리입니다. 주로 웹 스크래핑 작업에서 널리 사용됩니다.
라이브러리 설치
bs4와 관련된 의존성 패키지를 설치합니다.
pip install bs4 -i https://pypi.tuna.tsinghua.edu.cn/simple/
pip install lxml
lxml은 파이썬에서 HTML을 빠르게 해석하기 위한 파서이며, 기본 내장 파서보다 성능이 우수합니다. BeautifulSoup가 사용할 파서로 지정할 수 있습니다.
모듈 임포트
from bs4 import BeautifulSoup
기본 구조: 솔루션 객체와 태그 객체
HTML 문자열을 파싱하여 솔루션 객체(soup)를 생성합니다.
soup = BeautifulSoup('<a href="#" class="c1">링크 텍스트</a><a>기타 내용</a>', 'lxml')
- 첫 번째 인자: 해석할 마크업 데이터 (문자열 또는 파일 객체)
- 두 번째 인자: 파싱 엔진 (예: 'lxml', 'html.parser')
솔루션 객체는 마크업 트리의 루트 역할을 하며, 태그 검색 및 필터링 기능을 제공합니다. 이 과정에서 얻어진 결과는 태그 객체로 표현되며, 해당 객체는 태그 이름, 속성, 텍스트 등을 접근할 수 있는 메서드와 속성을 가집니다.
솔루션 객체의 주요 메서드
문자열 출력 및 저장
솔루션 객체를 직접 출력하면 마크업이 나타나지만, 이를 변수에 저장하려면 str() 함수를 사용해야 합니다.
soup = BeautifulSoup('<a href="#">클릭 가능</a>', 'lxml')
print(soup) # <a href="#">클릭 가능</a>
stored_text = str(soup) # 문자열로 변환하여 저장
태그 이름으로 검색
솔루션 객체에 태그 이름을 직접 접근하면 첫 번째 일치하는 태그를 반환합니다.
soup.a.name # 'a'
soup.a.attrs # {'href': '#'}
find() 메서드
조건에 맞는 첫 번째 태그를 반환합니다.
soup.find('a') # 첫 번째 <a> 태그
soup.find('a', class_='c1') # class 속성이 'c1'인 <a> 태그
find_all() 메서드
조건에 맞는 모든 태그를 리스트로 반환합니다.
all_links = soup.find_all('a')
for link in all_links:
print(link.text)
select() 메서드 (CSS 선택자 지원)
CSS 선택자를 사용해 정교한 조건으로 태그를 추출할 수 있습니다.
soup.select('[href="#"]') # href 속성이 '#'인 태그
soup.select('.c1') # class가 'c1'인 태그
soup.select('div a') # div 아래에 있는 a 태그
text 속성: 태그 제거 후 텍스트만 추출
내부 모든 태그를 제거하고 순수 텍스트를 결합합니다.
soup = BeautifulSoup('<p>안녕 <em>세상</em></p>', 'lxml')
soup.text # '안녕 세상'
string 속성: 단일 텍스트 값 수정
내부 텍스트를 직접 변경할 수 있습니다.
span = soup.find('span')
span.string = '새로운 텍스트' # 텍스트 수정
decomposed() 메서드: 태그 삭제
지정된 태그를 트리에서 완전히 제거합니다.
[tag.decomposed() for tag in soup.find_all('script')]
LXML 파서의 XPath 지원
BeautifulSoup가 사용하는 lxml 파서는 XPath 문법도 지원합니다.
from lxml import etree
doc = '<body><div id="main"><a href="/home">홈</a></div></body>'
tree = etree.HTML(doc)
# 모든 요소 조회
tree.xpath('//a')
# 특정 속성 값 찾기
tree.xpath('//a[@href="/home"]')
# 부모-자식 관계 탐색
tree.xpath('//body/div/a[1]')
주요 XPath 식별자
| 표현식 | 의미 |
|---|---|
| / | 현재 레벨의 자식 |
| // | 재귀적으로 모든 하위 요소 |
| @attr | 속성 값 접근 |
| . | 현재 노드 |
| .. | 부모 노드 |
| //* | 모든 태그 |
이외에도 공식 문서를 참고하여 더 복잡한 구문 분석을 수행할 수 있습니다.