[Python_WebScrapping]Selenium

rssungjae·2021년 1월 11일
0

Python_WebScrapping🕵

목록 보기
2/2
post-thumbnail

git 바로가기


Requests
User Agent
BeautifulSoup
Selenium
Headless chrome
이미지 다운로드
csv 다운로드


Requests

  • 정적 웹 페이지 읽어오기
  • 빠르다, 동적 웹 페이지 불가
  • 주어진 url을 통해 받아온 html에 원하는 정보가 있을때
import requests
res = requests.get("http://google.com")
# Requests를 통해 받아온 html이 정상인지 확인
res.raise_for_status()
if res.status_code == requests.codes.ok:
    print("정상입니다.")
else:
    print("문제가 생겼습니다. [에러코드 ", res.status_code, "]")
# 해당 사이트 html 가져오기
with open("mygoogle.html", "w", encoding="utf8") as f:
    f.write(res.text)    

User Agent

header도 없이 request하게 되면 봇으로 이해하고 사이트측에서 접근을 차단시키는 경우가 있다. 이 경우, 자신의 PC에 User Agent를 header에 설정시켜 request할 수 있다.

import requests
url = "http://nadocoding.tistory.com"
headers = {"User-Agent" : "{자신의 User Agent}"}
res = requests.get(url, headers = headers)

BeautifulSoup

html과 xml 문서를 파싱하기위한 파이썬 패키지로서
웹 스크래핑에 유용한 html의 데이터를 추출하는데 사용가능

필요 라이브러리 설치

pip install bs4
pip install lxml

html태그를 분석할 수 있어야 한다.
태그를 찾고, class나 id로 구분지어 list형태에서 index를 이용해 원하는 값을 찾아야한다.
그리고 찾은 값을 정규식을 이용해 원하는 정보만을 스크래핑한다.

예시코드

import requests
from bs4 import BeautifulSoup

url = "https://comic.naver.com/webtoon/weekday.nhn"
res = requests.get(url)
res.raise_for_status()

soup = BeautifulSoup(res.text, "lxml")
print(soup.title)
print(soup.title.get_text())
print(soup.a) # soup 객체에서 첫 번재로 발견되는 a element 출력
print(soup.a.attrs) # a element의 속성 정보를 출력
print(soup.a["href"]) # a element의 href 속성 '값' 정보를 출력

# class="Nbtn_upload" 인 element를 찾음
print(soup.find("a", attrs = {"class":"Nbtn_upload"})) 
print(soup.find(attrs = {"class":"Nbtn_upload"}))

# 네이버 웹툰 전체 목록 가져오기
# list형태로 출력
cartoons = soup.find_all("a", attrs ={"class" : "title"})

스크래핑한 내용을 csv파일화 하기

filename = "./webscraping_basic/csv/시가총액1-200.csv"

# 엑셀파일 한글깨짐 현상 -> utf-8-sig
f = open(filename, "w", encoding = "utf-8-sig", newline="") 
writer = csv.writer(f)
title = "N	종목명	현재가	전일비	등락률	액면가	시가총액	상장주식수	외국인비율	거래량	PER	ROE".split("\t")
writer.writerow(title)

data_rows = soup.find("table", attrs={"class":"type_2"}).find("tbody").find_all("tr")
    for row in data_rows:
        columns = row.find_all("td")
        if len(columns) <= 1:
            continue
        data = [column.get_text().strip() for column in columns]
        # print(data)
        writer.writerow(data)

Selenium

웹 페이지 자동화
느리다, 동적 웹 페이지 가능
로그인, 어떤 결과에 대한 필터링 등 어떤 동작을 해야하는 경우
chromedriver.exe 가 반드시 있어야 한다.

필요 라이브러리 설치

pip install selenium
pip install lxml

예시코드

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
browser = webdriver.Chrome() # Chrome("위치")
# 1. 네이버 이동
browser.get("http://naver.com")
# 2. 네이버에서 id가 query인 태그 찾기
elem = browser.find_element_by_id("query")
# 3. 해당 태그에 값넣기
elem.send_keys("검색")
elem.send_keys(Keys.ENTER)

# elem.메소드
.click()

# browser.메소드
.back()
.forward()
.refresh()
.close()
.quit()

로딩될때까지 기다려야 할때


from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

try:
    # 검색 결과 대기
    elem = WebDriverWait(browser, 10)
    .until(EC.presence_of_element_located((By.XPATH, "copy한 xpath")))
    # 성공했을 때 동작 수행
finally:
    browser.quit()

# 스크롤 다운
import time
interval = 2 # 2초에 한번씩 스크롤 내림
# 현재 문서 높이를 가져와서 저장
prev_height = browser.execute_script("return document.body.scrollHeight")

# 반복 수행
while True:
    # 화면 가장 아래로 스크롤 내리기
    browser.execute_script("window.scrollTo(0, document.body.scrollHeight)")

    # 페이지 로딩 대기
    time.sleep(interval)

    # 현재 문서 높이를 가져와서 저장
    curr_height = browser.execute_script("return document.body.scrollHeight")
    if curr_height == prev_height:
        break
    
    prev_height = curr_height

Headless chrome

브라우저를 띄우지 않고 동작
때로는 User-Agent 정의 필요

from selenium import webdriver

options = webdriver.ChromeOptions()
options.headless = True
options.add_argument("window-size=2560x1080")

browser = webdriver.Chrome(options=options) # Chrome("위치")
browser.maximize_window() # 창 최대화

# 페이지 이동
url = "https://play.google.com/store/movies/top"
browser.get(url)

이미지 다운로드

with open("파일명", "wb") as f:
    f.write(res.content)

csv 다운로드

import csv
f = open(filename, "w", encoding("utf-8-sig", newline=""))
profile
hey!

0개의 댓글