Target
useragent를 추가하자. 구글링 하면 알 수 있다.
user_agent = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36"}
import requests
from bs4 import BeautifulSoup
res = requests.get("https://hashcode.co.kr/", user_agent)
soup = BeautifulSoup(res.text, "html.parser")
get의 두 번째 인자는 header이다. header는 key와 value로 되어 있다.
user-agent의 값을 이것으로 설정하라고 요청하는 것
soup.find("li","question-list-item").find("div","question").find("div","top").h4.text
>>> 'What is outstaffing?'
find(tag, class), find(tag, id='id')로 접근하고 class 같은 경우는 명시할 필요가 없다.
.h4로 클래스로 접근 가능하다.
import time
for i in range(1,6):
result= []
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)
time.sleep(0.5) # 0.5second sleep
Pagination 을 사용
웹 페이지는 어떻게 생성되냐에 따라 크게 2가지로 구분
HTML 내용이 고정된 정적(static)웹 사이트
정적 웹사이트는 HTML 문서가 완전하게 응답된다.
request를 요청했을 때, 응답이 오고 parsing을 해도 아무 문제 없다.
HTML 내용이 변하는 동적(dynamic)웹 사이트
e.g) instagram
동적 웹 사이트는 응답 후 HTML이 렌더링 될 때까지의 지연시간이 존재
웹 브라우저에선 JavaScript라는 프로그래밍 언어가 동작한다.
비동기 처리를 통해서 필요한 데이터를 응답 이후에 채운다.
동기 처리 : 요청에 따른 응답을 기다린다.
어떤 여러 작업이 진행될 때, 한 작업이 끝날 때, 그 작업의 결과가 돌아오는 것을 보장하냐 안하냐에 대한 차이.
비동기 처리 : 요청에 따른 응답을 기다리지 않는다.
동기 처리된 경우, HTML 로딩에 문제가 없다.
비동기 처리된 경우, 상황에 따라서 데이터가 완전하지 않은 경우가 발생한다.
렌더링이 이루어진 후에 우선 응답을 하고 데이터 처리가 이루어질 수 있다..
비동기 처리 상황에서 요청을 보내면 불완전한 응답을 받을 수 있다.
키보드 입력, 마우스 클릭등을 단순한 requests로는 진행하기 어렵다.
request는 단순히 요청 및 응답만 하기 때문이다..
임의로 시간을 지연한 후, 데이터 처리가 끝난 후 정보를 가져오면 된다.
키보드 입력, 마우스 클릭 등을 프로그래밍할 순 없을까? (web에선 event라고 부름)
지금까지는 웹브라우저를 대체하는 코드를 파이썬으로 구성했다.
이젠 웹 브라우저 자체를 파이썬으로 조작해보자.
웹브라우저를 자동화하는 라이브러리 Selenium이다.
응답 후 시간을 지연시킬 수 있다.
UI와의 상호작용이 가능하다.
동적 웹사이트는 응답 후 바로 정보를 추출하기 어렵다.
또한, 다양한 키보드 입력과 마우스 클릭 등의 상호작용이 존재한다.
이런 상황을 해결하기 위해, 웹 브라우저를 파이썬으로 조작하는 전략을 취하자
e.g) Login