데이터엔지니어링

[2주차] 파이썬으로 웹다루기 (3)

heecup 2024. 4. 3. 16:18

🙂 BeautifulSoup

from bs4 import BeautifulSoup
import requests

res = requests.get("http://www.example.com")

soup = BeautifulSoup(res.text, 'html.parser')

print(soup.prettify())

# soup.(태그이름)으로 정보를 가져올 수 있음.
soup.title
soup.head
soup.body

# <h1> 태그로 감싸진 요소 하나 찾기
h1 = soup.find("h1")

# <p> 태그로 감싸진 요소들 찾기
soup.find_all("p")

# 태그 이름 가져오기
h1.name

# 태그 내용 가져오기
h1.text

🙂 원하는 요소 가져오기 1

✔  책 이름 모으기

from bs4 import BeautifulSoup
import requests

res = requests.get('http://books.toscrape.com/catalogue/category/books/travel_2/index.html')
soup = BeautifulSoup(res.text, 'html.parser')

# <h3> 태그에 해당하는 요소
book = soup.find('h3')

# <h3> 태그에 해당하는 요소 모두 찾기
book_list = soup.find_all('h3')

# book_list에서 제목(title)만 추출
for book in book_list:
	print(book.a['title'])

🙂 HTML의 Locator로 원하는 요소 찾기

✔  tag의 id와 class 사용

from bs4 import BeautifulSoup
import requests

res = requests.get('http://programmers.co.kr/pages/data_engineering')
soup = BeautifulSoup(res.text, 'html.parser')

## id없이 div 태그 찾기
soup.find('div')

## id가 results인 div 태그 찾기
soup.find('div', id='results')

## class가 'page-header'인 div 태그 찾기
find_result = soup.find('div', 'page-header')
find_result.h1.text.strip()

🙂 원하는 요소 가져오기 2

✔  해시코드 질문 모으기

from bs4 import BeautifulSoup
import requests

## 누가 요청을 보내는 지 명시
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"}

res = requests.get('https://hashcode.co.kr/', user_agent)
soup = BeautifulSoup(res.text, 'html.parser')

##	<li class='question-list-item'>
##		<div class='question'>
##			<div class='top'>
##				<h4>text</h4>
##			</div>
##		</div>
##	</li>
## questions = soup.find('li', 'question-list-item').find('div', 'question').find('div', 'top').h4.text

questions = soup.find_all('li', 'question-list=iem')
for question in questions:
	print(question.find('div', 'question').find('div', 'top').h4.text)

 

Pagenation

## https://hashcode.co.kr/?page={i}
from bs4 import BeautifulSoup
import requests
import time

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"}

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=iem')
    for question in questions:
        print(question.find('div', 'question').find('div', 'top').h4.text)
    time.sleep(0.5)

 

이 방법으로 모든 웹사이트의 정보를 가져올 수는 없다.


🙂 동적 웹 페이지와의 만남

✔  정적 웹 사이트와 동적 웹 사이트

정적(static) 웹 사이트

HTML 내용이 고정

HTML 문서가 완전하게 응답

 

동적(dynamic) 웹 사이트

HTML 내용이 변함 (ex. 인스타그램 - 새로고침 시 피드 내용 갱신)

응답 후 HTML이 렌더링 될 때까지 지연시간 존재

✔  동작 방식

웹 브라우저에선 JavaScript라는 프로그래밍 언어가 동작.

 

동기 처리

요청에 따른 응답 대기 (렌더링 -> 데이터 처리)

HTML 로딩에 문제 X

 

비동기 처리

요청에 따른 응답 대기 X (렌더링과 데이터 처리 동시에 진행)

상황에 따라서 데이터가 완전하지 않은 경우 발생

✔  requests 요청 시 문제점

  • 불완전한 응답 가능성 존재
  • 키보드 입력, 마우스 클릭 등으로 진행 불가

해결 방안

  • 임의로 시간을 지연한 후, 데이터 처리가 끝난 후 정보를 가져옴
  • 키보드 입력, 마우스 클릭 등을 프로그래밍

-> 웹 브라우저를 파이썬으로 조작하자!

-> Selenium

✔  Selenium

from selenium import webdriver

driver = webdriver.Chrome()
driver.implicitly_wait(10)
driver.get('http://www.example.com')

elem = driver.find_element_by_tag_name('hello-input')
elem.send_keys('Hello!')