본문 바로가기
IT/Scraping

복잡한 HTML페이지를 분석하여 원하는 정보만 추출하기

by Cyber_ 2025. 1. 28.

고급 HTML 분석을 사용하지 않는 방법

bs.findAll('table')[4].find_all('tr')[2].find('td').find_all('div')[1].find('a')

 

이 방법의 문제점

  • 사이트 관리자가 사이트를 조금만 수정하더라도 웹 스크레이퍼에 동작이 멈출 수 있습니다.

그렇기에 태그의 위치, 문맥, 속성, 콘텐츠에 따라 태그를 선택하는 표준적이 창의적인 방법이 필요합니다.

 

속성값을 통해 탐색

오늘날 웹사이트 대부분은 class, id와 같이 고유한 속성을 가지고 있기에 요소를 찾기 수월합니다. BeaurifulSoup 객체의 findAll 함수를 사용하면 태그에 들어있는 텍스트만 선택해서 고유명사로 이루어진 파이썬 리스트를 추출할 수 있습니다.

nameList = bs.findAll('span', {'class':'green'}
for name in nameList:
    print(name.get_text())
  • findAll을 통해 페이지의 전체 태그에서 포함되는 요소들을 nameLIst에 할당 합니다.
  • name.get_text()를 호출해 태그를 제외하고 콘텐츠만 출력합니다.

find()와 findAll()

find()와 findAll()은 BeaurifulSoup에서 가장 자주 쓰이는 함수입니다.

findAll(tag, attributes, recursive, text, limit, keywords)
find(tag, attributes, recursive, text, keywords)
  • tag: 태그 이름 또는, 태그 문자열 리스트
  • attributes: 속성으로 이루어진 파이썬 딕셔너리
  • recursive: 기본적으로 재귀적(디폴트로) 작동하는 불리언 입니다.
  • text: 택스트 콘첸츠를 탐색합니다.
  • limit: 처음 몇 개에만 관심이 있을 때 사용되는 정수입니다.
  • keyword: 특정 속성이 포함된 태그를 선택할 대 사용

BeautifulSoup 객체

  • BeaurifulSoup 객체: bs와 같은 형태
  • Tag 객체: 리스트 호출 또는 BeaurifulSoup 객체에 find와 findAll을 호출한 값
  • NavigableString 객체: 태그가 자체가 아니라 태그 안에 들어 있는 텍스트를 나타냅니다.
  • Comment 객체: 주석 태그 안에 들어있는 HTML 주석을 찾는데 사용 됩니다.

트리 이동을 통해 탐색

속성값이 아닌 문서 안에서의 위치를 기준으로 태그를 찾을 때 사용

자식과 자손

Beautiful 함수는 항상 현재 선택된 태그의 자손을 다룹니다. .childern으로 찾을 수 있습니다.

형제 다루기

BeautifulSoup의 next_sibling() 함수는 테이블에서 데이터를 쉽게 수집할 수 있으며, 특히 테이블에 타이틀 행이 있을 때 유용합니다.

from urllib.request import urlopen
from bs4 import BeautifulSoup

html = urlopen('http://www.pythonscraping.com/pages/page3.html')
bs = BeautifulSoup(html, 'html.parser')

for sibling in bs.find('table', {'id': 'giftList'}).tr.next_sibling:
    print(sibling)

위 코드의 출력 겨로가는 첫 번째 타이틀 행를 제외한 모든 제품 행입니다. 객체 자신은 자신의 형제가 없기 때문에 타이틀 행은 제외되었습니다.

부모 다루기

.parent, .parents를 통해 찾을 수 있음

 

정규 표현식과 BeautifulSoup

from urllib.request import urlopen
from bs4 import BeautifulSoup
import re

html = urlopen('http://www.pythonscraping.com/pages/pages3.html')
bs = BeaurifulSoup(html, 'html.parser')
images = bs.findAll('img', {'src': re.compile('\.\.\/image\/gifts/img.*\.jpg)})
for image in images:
    print('src')

정규 표현식을 통해 이미지의 경로를 찾는 것을 도울 수 있습니다.

 

속성에 접근하기

때로는 콘텐츠가 아닌 속성을 찾고 싶을 때까 있습니다. 다음과 같이 태그 객체에서 속성 목록에 접근할 수 있습니다.

myTag.attrs

다음과 같이 속성을 찾아 올 수 있습니다.

myImgTag.attrs['src']

 

람다 표현식

BeautifulSoup는 특정 타입의 함수를 findAll 함수에 매개변수로 넘길 수 있습니다.
이들 함수는 반드시 태그 객체를 매개변수로 받아야 하고, 불리언만 반환할 수 있다는 제약만 있습니다.

bs.findAll(lambda tag: len(tag.attrs) == 2)

 

정리

속성값을 통해서 태그를 찾거나 태그에서 속성을 찾을 수 있고 정규표현식, 람다 표현식으로 요소들을 찾을 수 있습니다. 이 방법들은 자주 변하는 UI에서 요소들을 찾는 함수들의 유지보수성을 증진시켜줍니다.