Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
Tags
- 보기 편하라고 만든
- 부스트캠프
- 8기
- 운영체제론
- Ubuntu 20.04
- 후기
- Virtual Box 7.0.6
- 네이버 부스트 코스
- 웹/모바일
- 백준 #baekjoon # 2563
- 네이버
- id # tr # 환경변수
Archives
- Today
- Total
Miner
DAY 08 본문
10/25 - 파이썬으로 웹 데이터를 크롤하고 분석하기(3)
1. HTML 을 분석해주는 BeautifulSoup
▶ requests 모듈의 res.text 의 문제점 : 원하는 요소만을 분석하기가 어려움
따라서, HTML 코드를 분석해주는 HTML Parser를 사용한다.
BeautifulSoup4 모듈에서 사용한다.
1.
%pip install beautifulsoup4
2.
import requests
res = requessts.get("https://www.naver.com")
import bs4 import BeautifulSoup
soup = BeautifulSoup(res.text, "html.parser")
print(soup.prettify())
하면 정리된 html 코드가 나옴
3.
# title 가져오기
soup.title
# head 가져오기
soup.head
# body 가져오기
soup.body
# h1 태그로 감싸진 요소 가져오기
soup.find("h1")
# p 태그로 감싸진 모든 요소들 찾기
soup.find_all("p")
# 태크 이름 가져오기
tag1 = soup.find("h1")
tag1.name
# 태그 내용 가져오기
tag1.text
2. 원하는 요소 가져오기1 - 책 이름 모으기
오른쪽 마우스 - 검사 를 누르면 해당 내용이 어디 위치에 있는지 알려준다
1. 책 이름이 html 코드에 h3 태그 속에 위치해 있다는 것을 확인
2.
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")
book = soup.find("h3")
h3_result = soup.find_all("h3")
book.a.text
# 결과 "It's Only the Himalayas"
for book in h3_result:
print(book.a.text)
# 결과
Its Only the Himalayas
Full Moon over Noahâs ...
처럼 잘려서 나옴
for book in h3_result:
print(book.a["title"])
# title 속성으로 접근
# 결과 : 풀네임으로 나옴
3. HTML의 Locator로 원하는 요소 찾기
▶ 전 강의 에서 h3 태그를 가져오는 실습을 했는데 태그가 중복되는 경우 원치않는 내용까지 가져오기도 함
따라서 tag의 id 와 class를 활용하는 방법
Html 에서의 역할
- tagname : 태그의 이름
-
<p>This element has only tagname</p>
-
- id : 하나의 고유 태그를 가리키는 레벨
-
<p id="target">This element has tagname and id</p>
-
- class : 여러 태그를 묶는 라벨
-
<p class="targets">This element has tagname and class</p>
-
사용법
## id 없이 div 태그를 찾아봅시다.
soup.find_all("div")
## id가 results인 div 태그를 찾아봅시다.
soup.find("div", id="result")
# class가 "page-header"인 div 태그를 찾아봅시다.
find_result = soup.find("div", "page-header")
# 결과에 양쪽 공백 제거
find_result.h1.text.strip()
4. 원하는 요소 가져오기 2
▶ 2가지 원칙을 지키면서 많은 정보를 가져오기
- 과도한 요청을 보내지 않는다.
- 받아온 정보 활용에 유의한다.
1. User-Agent를 추가한.
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"}
2.
import requests
from bs4 import BeautifulSoup
res = requests.get("https://qna.programmers.co.kr/", user_agent)
qus = soup.find_all("div", "top")
for que in qus:
print(que.h4.text)
※ 주의점 : soup.find_all("div", "top").h4 이렇게 all 을 쓰면서 h4 태그까지 가져올 수 없음
3. 페이지네이션
페이지네이션은 많은 정보를 인덱스로 구분하는 기법입니다.
Query String을 통해 구분
# Pagination이 되어있는 질문 리스트의 제목을 모두 가져와봅시다.
# 과도한 요청을 방지하기 위해 1초마다 요청을 보내봅시다.
import time
for i in range(1,6):
res = requests.get("https://hashcode.co.kr/?page={}".format(i), headers=user_agent)
soup = BeautifulSoup(res.text, "html.parser")
qus = soup.find_all("div", "top")
for que in qus:
print(que.h4.text)
time.sleep(0.5)
5. 동적 웹 페이지와의 만남
▶ 위와 같은 방법으로 할 수 있으면 좋지만 현대 웹 페이지는 동적으로 움직이기 때문에 더 확장된 기술이 필요
- 정적 웹 사이트와 동적 웹 사이트
- 정적 웹 사이트 : HTML 내용이 고정된 정적 웹 사이트, HTML 문서가 완전하게 응답한다.
- 동적 웹 사이트 : HTML 내용이 변하는 정적 웹 사이트 ex) 인스타그램, 응답 후 HTML이 렌더링이 될 때까지의 지연시간이 존재한다.
- 동적 웹 사이트의 동작 방식 : 자바스크립트가 동작한다. 비동기 처리를 통해서 필요한 데이터를 채운다.
- 비동기 처리 : 요청에 따른 응답을 기다리지 않는다 (동시에)
- 동기 처리 : 요청에 따른 응답을 기다린다
- 동기 처리의 경우 HTML 로딩에 문제가 없다. 비동기 처리의 경우 상황에 따라서 데이터가 완전하지 않은 경우가 발생한다.
- 비동기 처리가 이루어지는 중에 요청을 보내면 불완전한 응답을 받게 된다. 키보드 입력, 마우스 클릭 등을 requests 로는 진행하기 어렵다
- 임의로 시간을 지연 후, 데이터처리가 끝나면 정보를 가져오면 된다.
- UI action 도 생각을 해야 한다.
- 동적 웹사이트는 응답 후 바로 정보를 추출하기 어렵다(비동기 방식, 키보드 입력과 마우스 클릭 등의 상호작용)
- 결론적으로 웹 브라우저를 파이썬으로 조작하자는 이야기 (이 버튼을 클릭해, 이 입력창에 "hello"를 입력해 etc)
- 파이썬에서 웹 브라우저를 자동화하는 라이브러리 Selenium
- 응답 후 시간을 지연시키는 코드를 작성 할 수 있다.
- UI 와의 상호작용이 가능하게 한다.