BeutifulSoup이란, Python의 라이브러리로 requets로 얻은 html 텍스트를 파싱해 주는 역할을 한다.
import requests
from bs4 import BeautifulSoup
user_agent = {key : value for key, value in _.items()} # user_agent에 대한 정보.
res = requests.get("URL", user_agent) # 해당 URL 페이지에게 get 요청.
soup = BeautifulSoup(res.text, "html.parser") # html 문서인 res.text를 파싱하는 BeutifulSoup 객체 생성.
soup.prettify() # 해당 html 코드를 예쁘게 보여줌.
soup.title # 해당 html 코드의 title. soup.head, soup.body, soup.h1 .. 처럼 응용가능함.
soup.find("h1") # 위와 유사하게 "h1"이라는 태그의 요소 및 컨텐츠들을 갖고 옴.
# 다만 여러 개일 경우, 가장 먼저 나타나는 것을 갖고 옴.
soup.find("h1", "class_name") # class 속성 값이 "class_name"인 "h1" 태그를 갖고 옴.
soup.find("h1", id="id_name") # id 속성 값이 "id_name"인 "h1" 태그를 갖고 옴.
soup.find_all("h1") # 모든 "h1"를 갖고 옴.
soup.find("h1").name # "h1" 태그 객체의 태그 이름을 갖고 옴.
soup.find("h1").text # "h1" 태그 객체의 콘텐츠를 갖고 옴.
soup.find("h1")["title"] # "h1" 태그 객체의 title 속성 값을 갖고 옴.
# 여러 icon들의 정보를 리스트에 저장하는 예시 코드.
# <ul><li class="service-icon"><h4 id="icon1">icon1_name</h4></li> .. </ul>
objs = soup.find_all("li", "service-icon")
icons = []
for obj in objs:
icon = obj.h4.text
icons.append(icon) # "icon{number}_name"이 아마 append될 것임.
HTML 태그의 속성 중 class와 id는 다음과 같은 특징이 있다.
어떤 사이트를 방문하다 보면, 여러 개의 페이지를 갖는 사이트가 있을 것이다.
그리고 대부분의 사이트인 경우, page 번호에 따른 페이지 주소는 "URL/page={#}"으로 되어 있다. 이를 활용하면 여러 개의 페이지에 대해서 작업을 진행할 수 있다.
(다만, 너무 빨리 작업을 수행하면 서버에 무리가 갈 수 있으니 time.sleep()을 활용한다.)
import requests
from bs4 import BeautifulSoup
import time
pageCount = 10
for i in range(1, pageCount+1):
res = requests.get(f"URL/page={i}", header= )
soup = BeautifulSoup(res.text, "html.parser")
objs = soup.find_all("~~") # 객체 모음 objs를 저장한 후,
for obj in objs:
print(obj.find("~~").text) # 객체 obj에 대한 연산 진행.
time.sleep(0.5) # 0.5초 간 멈춤.
이처럼 Python의 BeautifulSoup 라이브러리를 활용하여, 원하는 요소만 추출하는 HTML Parser를 유용하게 사용할 수 있다. 하지만, 현대의 웹 페이지는 순수하게 HTML 내용이 고정된 정적 웹 페이지가 아니다. 대부분 JavaScript와 같은 코드가 있으며, 웹 페이지의 HTML 코드가 실시간으로 변경될 수 있다. 따라서 동적 웹 페이지에 대해서 처리하는 방법이 필요하다.
정적 웹 사이트 | 동적 웹 사이트 | |
---|---|---|
HTML 내용의 변동성) | HTML 내용이 고정된 웹 사이트 | HTML 내용이 가변적인 웹 사이트. |
응답 후 바로 파싱 시의 문제점) | 완벽한 응답. 바로 파싱 가능함. | 응답 후 HTML 내용이 렌더링될 때까지의 시간이 필요함. 바로 파싱 시 문제 발생 가능. |
동적 웹 사이트의 경우 다음과 같은 동작 방식을 따른다.
JavaScript 코드 -> 비동기 처리 -> 선 응답, 후 데이터 처리
따라서, 단순 requests로 스크래핑 시 데이터 처리가 아직 부족할 가능성이 높다.
이를 위해 다음과 같은 보완책이 모색되었다.
그리고 이러한 작업들을 Python으로 수행할 수 있게 해주는 라이브러리가 Selenium 이다.
Selenium : 웹 브라우저의 자동화 라이브러리