HTML을 분석해주는 BeautifulSoup
원하는 요소 가져오기 1
HTML의 Locator로 원하는 요소 찾기
원하는 요소 가져오기 2
동적 웹페이지와의 만남
BeautifulSoup 라이브러리
HTML 코드를 분석해주는 HTML Parser
BeautifulSoup(response_body, "html.parser")
첫 번째 인자는 response의 body를 텍스트로 전달
두 번째 인자는 "html"로 분석한다는 것을 명시
.pretify()
import requests
from bs4 import BeautifulSoup
res = requests.get("http://www.example.com")
soup = BeautifulSoup(res.text, "html.parser")
print(soup.prettify())
# title 가져오기
print(soup.title)
# head 가져오기
print(soup.head)
# body 가져오기
print(soup.body)
# <h1> 으로 감싸진 요소 하나 찾기
print(soup.find("h1"))
# <p> 로 감싸진 요소들 찾기
print(soup.find_all("p"))
# 태그 이름, 내용 가져오기
h1 = soup.find("h1")
print(h1.name)
print(h1.text)
사용할 사이트: http://books.toscrape.com/catalogue/category/books/travel_2/index.html
특정 태그로 스크래핑하는 것은 직관적이지만 좋음 방법은 아님
크롬에서 검사를 원하는 요소를 우클릭한 뒤 "검사"를 누르면 개발자 도구가 켜지면서 해당 요소 가리킴
찾아온 데이터들은 모두 객체이므로, 아래와 같이 접근할 수 있음
book = soup.find("h3")
# <h3> 안에 있는 <a>의 콘텐츠 추출
book.a.text
import requests
from bs4 import BeautifulSoup
res = requests.get("http://books.toscrape.com/catalogue/category/books/travel_2/index.html")
soup = BeautifulSoup(res.text, "html.parser")
# <h3> 에 해당하는 요소 모두 검색해 제목(Title)만 추출
h3_results = soup.find_all("h3")
for book in h3_results:
# 속성(Attribute)은 딕셔너리처럼 접근
print(book.a["title"])
id와 class는 Locator로서, 특정 태그를 지칭하는 데 사용
id: 하나의 고유 태그를 가리키는 라벨
class: 여러 태그를 묶는 라벨
사용할 사이트: http://example.python-scraping.com/
import requests
from bs4 import BeautifulSoup
res = requests.get("http://example.python-scraping.com/")
soup = BeautifulSoup(res.text, "html.parser")
# id가 "results"인 div 검색
print(soup.find("div", id = "results"))
# class가 "page-header"인 div 검색
find_result = print(soup.find("div", "page-header"))
# 텍스트 깔끔하게 출력
print(find_result.h1.text.strip())
사용할 사이트: https://hashcode.co.kr/
아래의 두 가지 원칙을 지키며 스크래핑하기
페이지네이션(Pagination)
웹사이트의 정보를 인덱스로 구분하는 기법
많은 웹사이트들이 Query String을 사용해 구분
- https://www.example.com/?page={i}
import requests
from bs4 import BeautifulSoup
import time
# 스크래핑을 위해 user agent 추가
user_agent = {"User-Agent": "Mozilla/5.0 ..."}
# Pagination 되어있는 질문 리스트의 제목 모두 추출
# 1page ~ 5page
for i in range(1, 6):
res = requests.get("https://hashcode.co.kr/?page={}".format(i), user_agent)
soup = BeautifulSoup(res.text, "html.parser")
questions = soup.find_all("li", "question-list-item")
for question in questions:
# 계층 구조를 연쇄적으로 접근해 질문글의 제목만 추출
print(question.find("div", "question").find("div", "top").h4.text)
# 과도한 요청을 방지하기 위해 1초씩 지연
time.sleep(1)
정적 웹사이트와 동적 웹사이트
생성 방식에 따른 구분
HTML이 고정된 정적(Static) 웹사이트, 내용이 변하는 동적(Dynamic) 웹사이트
정적 웹사이트는 HTML 문서가 완전하게 응답
동적 웹사이트는 응답 후 HTML이 렌더링될 때까지 지연시간이 존재
동적 웹사이트의 동작 방식
Javascript라는 프로그래밍 언어가 동작하며 비동기 처리를 통해 데이터를 채움
동기 처리: 요청에 대한 응답을 기다림
비동기 처리: 요청에 대한 응답을 기다리지 않음
불완전한 응답을 받는 것을 방지하기 위해 임의로 시간을 지연한 뒤 정보를 가져옴
키보드, 마우스 입력 등의 이벤트(상호작용)을 처리하기 위해 웹 브라우저를 파이썬으로 조작
import 'requests' could not be resolved from source Pylance reportMissingModuleSource
requests.get(URL) 할 때 URL은 "https://"부터 전부 적어줘야 함