Miner

DAY 08 본문

데브코스

DAY 08

MineTime76 2023. 10. 25. 17:25

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. 과도한 요청을 보내지 않는다.
  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 와의 상호작용이 가능하게 한다.

 

'데브코스' 카테고리의 다른 글

DAY 11  (0) 2023.10.30
DAY 09  (0) 2023.10.26
DAY 07  (0) 2023.10.24
DAY6 - 파이썬으로 웹 다루기  (1) 2023.10.23
Day03  (0) 2023.10.18