DOM
1. BeautifulSoup
- HTML, XML 파일에서 데이터를 가져올 수 있는 파이썬 라이브러리
- BeautifulSoup을 이용해 DOM 객체로 변환할 수 있음
!pip install beautifulsoup4
from bs4 import BeautifulSoup
2. Parser
- html parser: 내장되어 있어 별다른 패키지의 도움을 받을 필요가 없음
- lxml parser: 속도가 빠르다는 장점이 있고 아나콘다를 설치하면 포함되어 있음
3. Dom 객체 만들고 Parsing하기
html = '''
<html>
<head>
<title>예제</title>
</head>
<body>
<div>
<p>
<a href='/page' class='d' id=adf>페이지이동1</a>
<a>페이지이동2</a>
</div>
</p>
<footer>
<a class='d'>페이지이동3</a>
</footer>
</body>
</html>
'''
dom = BeautifulSoup(html, 'html.parser')
dom.text
# 내용만 보기
# '\n\n\n예제\n\n\n\n\n페이지 이동\n\n\n\n\n'
4. 탐색
다음 예시와 같이 다양한 방법으로 원하는 태그, 원하는 어트리뷰트, 텍스트에 접근할 수 있다.
dom.html
dom.html.head.title
dom.html.head.title.text # 텍스트 보기
dom.p
dom.body
list(dom.body.children) # 자식요소 리스트로 보기
dom.a.attrs # 속성을 key value 상으로 출력
dom.a['href']
dom.find('a')
dom.find_all('a')[-1].text # 텍스트 보기
dom.find_all({'p', 'a'})
dom.find_all('a', {'id':'adf'}) # 어트리뷰트 검색
dom.find_all(text='페이지이동1') # 텍스트 검색
dom.find_all('a', limit=1) # 개수 제한
node = dom.footer.a
type(node) # bs4.element.Tag
node.find_parent().name # 부모의 이름 찾기
for _ in dom.div.find_all(recursive=False): # 자기 출력 안하기
print(_.name)
# p
for _ in node.find_parents(limit=2):
print(_.name)
# footer
# body
node.find_parent().find_parent().find().find('a').find_next_sibling() # <a>페이지이동2</a>
- find (name, attrs, recursive, string, **kwargs)
- 하나만 찾기
- find_all (name, attrs, recursive, string, limit, **kwargs)
- 모든 자식에 대해 iterate 가능
- Recursive=False을 지정하면 direct children만 고려한다.
- find_parent()
- 해당 요소의 부모 찾기
- find_parents()
- 해당 요소의 모든 부모에 대해 iterate 가능
- find_next_sibling(s), find_previous_sibling(s)
- 같은 레벨에서 탐색
5. prettify()
html = '''
<html>
<head>
<title>예제</title>
</head>
<body>
<div>
<p>
<a href='/page' class='d' id=adf>페이지이동1</a>
<a>페이지 이동2</a>
</div>
</p>
</body>
</html>
'''
dom = BeautifulSoup(html, 'lxml')
print(dom.prettify()) # 태그 순서에 맞게 수정해줌
6. CSS Selector
tag1 tag2
: 자손- find_all(recursive=True)와 같음
tag1 > tag2
: 자식- find_all(recursive=False)와 같음
tag1 + tag2
: 형제 (다음노드)- find_next_sibling과 같음
resp = download('http://pythonscraping.com/pages/page3.html')
dom = BeautifulSoup(resp.text, 'lxml')
# id가 footer인 태그의 텍스트 가져오기
dom.select_one('#footer').text.strip()
# id가 wrapper인 태그의 자식 요소 이름 가져오기
{_.name for _ in dom.select('#wrapper > *')}
# h1 태그 -> 다음노드 div -> 이전노드 h1
dom.select_one('h1 + div').find_previous_sibling().name
# body 밑에 div 밑에 있는 h1 옆에 있는 div 찾기
dom.select_one('body > div > h1 + div').name
# 클래스가 gift인 태그의 자식요소 td 중 3번째 텍스트 가져오기
[_.text.strip() for _ in dom.select('.gift > td:nth-of-type(3)')]
# 클래스가 gift인 태그 밑 td 밑 img의 src 가져오기
[_['src'].strip() for _ in dom.select('.gift > td > img')]
Leave a comment