! -- web browser에서 직접적인 url을 가져와 parsing하는 web crawling은 아니지만 web에 존재하는(또는 컴퓨터에 자체적으로 존재하는) HTML file 내용을 가져와 나타내는 방법을 알아본다 -- !
** BeautifulSoup library tolerates highly flawed HTML & still lets you easily extract the data you need
(repairs & parses HTML to make it easier for a program to understand)
1. import & parsing
1> BeautifulSoup import
2> open()의 read() method를 사용하여 sample.html file을 받는다. (encoding은 utf-8 방식)
3> BeautifulSoup(class constructor)을 사용해 dirty HTML을 clean soup으로 변경: returns the entire document at that web page
(BeaufitulSoup knows how to deal with utf-8 string - 즉 utf-8을 unicode형식으로 변경)
* html.parser: Python 3 library에 속한 HTML parser
4> soup 객체의 prettify() 함수를 사용해 html 구조를 파악하기 쉽게 출력해 준다.
from bs4 import BeautifulSoup
page = open('sample.html','rt',encoding='utf-8').read()
soup = BeautifulSoup(page,'html.parser')
print(soup.prettify())
(+) sample.html (예시) 내용
<!DOCTYPE html>
<html>
<head>
<title>
아주 쉬운 HTML문서 샘플입니다.
</title>
</head>
<body>
<div>
<p class="inner-text first-item" id="first">
교육센터
<a href="http://www.credu.com" id="credu">
크레듀
</a>
</p>
<p class="inner-text second-item">
파이썬 사이트
<a href="https://www.python.org" id="python">
Python
</a>
</p>
</div>
<p class="outer-text first-item" id="second">
<b>
데이터 과학은 멋집니다.
</b>
</p>
<p class="outer-text">
<b>
지속적인 학습이 필요합니다.
</b>
</p>
</body>
</html>
2. find_all() & find()로 원하는 내용 출력하기
* prettify()의 output을 통해 전체적인 html 구조를 파악했으며, 이젠 html의 원하는 tag 이름을 두 find()에 집어넣어 tag 내용을 출력한다
* find_all() 함수는 특정 tag를 모두 검색하는 함수이고, find() 함수는 특정 tag 한 개(첫번째 한 개)만 검색하는 함수이다
[1] 기초 & 특성 class_, id 가지는 tag 찾기
Q) 예를 들어 p tag 한 개만 검색하고 싶거나 & outer-text class 속성을 가지는 모든 p tag를 검색하고 싶을 때
print(soup.find('p'))
print(soup.find_all('p',class_='outer-text'))
print(soup.find("p", {"class":"outer-text"})) # same with the 2nd row code
* 출력결과) '더보기' 클릭
- find
<p class="inner-text first-item" id="first">
교육센터
<a href="http://www.credu.com" id="credu">
크레듀
</a>
</p>
- find_all
[<p class="outer-text first-item" id="second">
<b>
데이터 과학은 멋집니다.
</b>
</p>, <p class="outer-text">
<b>
지속적인 학습이 필요합니다.
</b>
</p>]
Q) tag의 id 속성이 first인 경우를 검색하고 싶을 때
print(soup.find_all(id='first'))
* 출력결과 - 더보기 클릭
[<p class="inner-text first-item" id="first">
교육센터
<a href="http://www.credu.com" id="credu">
크레듀
</a>
</p>]
[2] get_text() - 내부 contents 상세 출력
Q) 특정 tag안의 문자열을 반환하고 싶을 때 (get_text() 사용) - 내부 콘텐츠만 반환하고 싶을 때
for tag in soup.find_all('p'):
print(tag.get_text())
* 출력결과 - 더보기 클릭
[3] 두 종류의 tag 반환 - list 형태 인자
Q) 두 종류의 tag - p & a tag들을 반환하고 싶을 때 - list 형태로 find_all() 인자에 집어넣어 반환 가능
print(soup.find_all(['a', 'p']))
* 출력결과 - 더보기
[<p class="inner-text first-item" id="first">
교육센터
<a href="http://www.credu.com" id="credu">
크레듀
</a>
</p>, <a href="http://www.credu.com" id="credu">
크레듀
</a>, <p class="inner-text second-item">
파이썬 사이트
<a href="https://www.python.org" id="python">
Python
</a>
</p>, <a href="https://www.python.org" id="python">
Python
</a>, <p class="outer-text first-item" id="second">
<b>
데이터 과학은 멋집니다.
</b>
</p>, <p class="outer-text">
<b>
지속적인 학습이 필요합니다.
</b>
</p>]
[4] lambda function 정의하여 검색하기
* lambda 특정 함수(일회성 함수)로 만들어 해당 함수의 반환값으로 원하는 tag를 검색할 수 있다.
→ tag의 속성값이 1개인 tag만 선택하여 해당 tag를 반환하는 lambda 함수를 만들고 find_all()에 집어넣어 반환한다
print(soup.find_all(lambda tag:len(tag.attrs) == 1))
* 출력결과 - 더보기
[<p class="inner-text second-item">
파이썬 사이트
<a href="https://www.python.org" id="python">
Python
</a>
</p>, <p class="outer-text">
<b>
지속적인 학습이 필요합니다.
</b>
</p>]
3. re 모듈과 결합하여 '더 상세하게' 검색하기
* 정규표현식 pattern을 정의하는 python에 내장된 re module
→ re를 통해 수많은 tag들 중 원하는 tag를 정규표현식(regular expression)을 사용하여 더 효율적이게 검색할 수 있다.
→ 주로 re.compile() 활용
import re
Q) a로 시작하는 tag name의 tag만 검색
tagsStartingWitha = soup.findAll(re.compile('^a'))
print(tagsStartingWitha)
print([tag.name for tag in tagsStartingWitha])
→ 출력결과) 더보기 클릭
[<a href="http://www.credu.com" id="credu">
크레듀
</a>, <a href="https://www.python.org" id="python">
Python
</a>]
['a', 'a']
→ findAll의 결과 'a'로 시작하는 총 tag들의 집합체가 list 형태로 tagsStartingWitha에 저장된다
→ 해당 list의 각각의 tag의 tag.name을 print하면 해당 HTML 파일에 존재하는 'a로 시작하는' 태그명이 출력된다.
Q) b로 끝나는 tag name의 tag만 검색
→ re.compile 인자에 "b$"를 집어넣는다
BeautifulSoup 간단 학습 끝! 🤟
* 출처) 2021 공공데이터 청년인턴(일경험수련생) 상시교육
'Python > Web Crawling+Scraping' 카테고리의 다른 글
Web Crawling(Scraping) 개요 + DOM 기초 (0) | 2022.04.05 |
---|---|
(예제) - 한국 도쿄올림픽 medal count 가져오기 - (0) | 2022.03.22 |
Crawling/Scraping에 필요한 HTML5 & CSS3 (간단 정리) (0) | 2022.03.21 |
댓글