BeautifulSoup
HTML, XML 문서를 구조적으로 분석하여 원하는 데이터를 쉽게 추출하게 도와주는 모듈.
bs4 (버전4)를 사용하기를 권장함.
간단하게 요약
- 설치
pip install beautifulsoup4
pip install lxml
from bs4 import BeautifulSoup
soup = BeautifulSoup(html) # html 문서를 파싱한다. (string, network connection 등)
print(soup.prettify()) # HTML을 이쁘게 출력한다.
soup.title # <title>hello</title>
soup.title.string # hello
soup.title.parent.name # head
soup.p # <p class="tt"><b>hi</b></p>
soup.p['class'] # tt
soup.a # <a class='sister' href='http://abc.com/el' id='link1'>El</a>
soup.find_all('a') # [<a>..</a>, <a>...</a>, <a>..</a> ]
soup.find(id='link3') # <a href="http://abc.com/ea', id='link3'>EA</a>
for link in soup.find_all('a'):
print(link.get('href')) # http://....
soup.get_text() # hello hi El....
- BeautifulSoup(markup, parser)
- markup : html 문서 스트링, html 문서 파일핸들, 네트웍 커넥션 등
- parser : ‘html.parser’ 또는 ‘lxml’
- lxml이 더 빠르고 관대함. xml도 지원.
- 태그 출력은 preffify() : 이쁘게 출력한다. soup.prettify()
- 그대로 출력하려면 str()로 타입캐스팅. str(soup)
- 태그는 .태그명으로 접근한다. 기본적으로 이름이 있고 .name 으로 알 수 있으며 name을 변경하면 문서에도 반영된다.
- soup.p = “div”
- 태그의 속성은 [속성]으로 접근한다. 또는 get()으로 접근할 수 있다. 속성은 .attrs로 알 수 있다.
- soup.p.attrs # 속성목록 조회 {‘class’:‘bold’}
- soup.p[‘class’] : 속성을 구한다. 키가 없으면 KeyError 발생
- soup.p.get(‘class’) : 위와 같지만 키가 없으면 None리턴으로 존재여부 체크를 할 수 있음.
- 속성값이 여러개면 리스트로 반환된다.
- 태그의 속성 수정
- soup.p[‘class’]=‘verybold’
- soup.p[‘id’]=1
- soup.p
<p class="verybold" id="1">
- del soup.p[‘class’] # 속성 삭제
- 스트링 변경
- soup.p.string.replace_with(“new text”)
- 스트링 추출 (string vs text)
- soup.p.string : p태그 내의 스트링. 주의! 내부에 순수하게 스트링만 존재해야함. 아니면 None. (태그가 있어도 안됨.)
- soup.p.text 또는 soup.p.get_text() : 내부의 텍스트를 전체 가져옴.
- 태그의 자손. 리스트로 리턴한다.
- soup.p.contents : 리스트로 가져온다.
find / find_all
태그를 찾는다. 클래스나 아이디로도 검색가능. find는 한 개를 찾고 find_all은 복수개를 찾는다. find_all은 리스트로 리턴한다.
- find_all(“title”) : title태그를 모두 찾는다.
- find_all(“p”, “title”) : p태그 중 class가 title인 태그를 모두 찾는다.
- find_all(id=“link2”) : ID로 찾는다.
- find_all(class_=re.compile(“itl”)) : 클래스명에 itl이 들어간 태그들 모두 추출
- find_all(text=“elise”) : 문자열 찾기
- find_all(“a”, text=“elise”) : 태그내의 문자열로 태그 찾기
- 정규식 지원
- soup.find_all( re.compile("^b")) : b로 시작하는 태그 모두 추출. ( b, body 등)
- 여러 태그 추출도 가능
- soup.find_all([“a”, “b”]) : 리스트로 주면 리스트내의 태그들을 모두 찾는다.
- find_all(“a”, limit=2) : 최대 2개만 찾는다.
- find_all(“title”, recursive=False) : 1뎁스(직계차일드)만 검색함. 예를 들면 soup.html.에서 위와 같이 찾으면 [] 리턴(not found.)
- find_all() 대신 ()만 사용해도 같다. (함수이름 생략) 예를 들면 soup.title.find_all(text=True)는 soup.title(text=True) 와 동일.
- find()는 처음 발견된 한 개만 리턴. (find_all에서 limit=1을 주면 동일한데, 리스트가 아닌 스트링(태그객체)으로 리턴.)
- Not Found인 경우, find()는 None 리턴. find_all()은 [] 리턴.
find_parent/ find_parents
- find / find_all의 반대. 상위계층으로 올라가면서 찾는다.
- a_string = soup.find(text=‘top10’) # u’top10’
- a_string.find_parents(“a”) # [ a태그들을 가져옴 ]
- a_string.find_parent(“p”) # p태그를 가져옴.
select
- soup.select(선택자) : css 선택자로 검색한다. 그냥 태그를 쓰면 태그 검색. 항상 리스트로 리턴함.
- soup.select(‘title’)
- soup.select(“body a”)
- soup.select(“html head title”)
- soup.select(“head > title”) : 헤드내부에 1단계 뎁스에서 title 찾기.
- 클래스 찾기 : soup.select(".sister") 또는 soup.select("[class~=sister]")
- ID로 찾기 : soup.select("#link1")
- 속성으로 찾기
- soup.select(‘a[href=“http://abc.com/elise”]’)
- soup.select(‘a[href^=“http://abc.com/”]’) : 이것으로 시작하는 링크들. 끝나는 링크는 href$를 사용.
get_text
- 텍스트 부분만 모두 추출한다. 하나의 스트링을 만들어 리턴.
- .text로 해도 된다.
strings/stripped_strings
- 둘 다 스트링들만 리스트로 추출하는 건데, stripped_strings는 필요없는 것을 제거함.
- 줄바꿈, 공백 등 필요없는 것들에 제거한 스트링 리스트를 리턴. [text for text in soup.stripped_strings]
Author: crazyj7@gmail.com
'Python' 카테고리의 다른 글
파이썬 개발환경/가상환경구축 (0) | 2019.12.01 |
---|---|
진법 표현 및 수 스트링 변환 (0) | 2019.11.24 |
크롤링(Crawl) 2편 (2) | 2019.10.27 |
웹 크롤링 Crawl 1편 (0) | 2019.10.24 |
인코딩에러 cp949 (1) | 2019.10.02 |