Post

파이썬 스크래핑하기

파이썬 스크래핑하기

공지고 프로젝트는 학과마다의 공지사항을 모두 가져와서 모바일에서 보기 편한 형태로 바꿔서 보여주는 프로젝트이다 여기서 학과마다 공지사항을 어떻게 가져왔는지 크롤링의 방법에 대해서 적었다

파이썬 스크래핑

파이썬에서 스크래핑을 한다고하면 대표적으로 사용되는 라이브러리 2개가 있다

  1. beautifulsoup
  1. selenium

이 두가지를 이용해서 스크래핑을 할 수 있는데 사용하는곳의 차이가 있다

beautifulsoup는 정적 페이지에서 이용할때 사용하고 selenium은 동적 페이지에서 사용한다 만약 beautifulsoup를 이용해서 크롤링을 했는데 결과가 제대로 나오지 않는다면 그 페이지는 동적페이지일 확률이 있다 그때는 selenium을 추가로 사용해야한다

 

 

정적페이지 스크래핑

정적 페이지를 파이썬으로 스크래핑하는 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import requests
from bs4 import BeautifulSoup

def scrap_page(url, selector1):
    res = []
    html = BeautifulSoup(requests.get(url).text, 'html.parser')
    
    for v in html.select(selector1):   
        res.append(v)
    return res

url = '목표 url'
selector = '태그 or 클래스 or 특성'
contents = scrap_list_page(url, selector1)

위 코드에 url에는 스크래핑할 url이 들어가고 selector에는 html에서 어디를 찾을 것인지를 결정한다

html = BeautifulSoup(requests.get(url).text, ‘html.parser’)를 통해서 페이지의 html을 text로 받아오고 html에 저장한다 select에 해당하는 부분 전부를 리스트화 시킨다 for문을 통해 각각을 처리할 수 있다

 

select 이용

형태설명
select(’a’)a태그를 찾는다
select(’body a’)body아래에 a 태그를 찾는다
select(’body > a’)body 바로 아래에 있는 a 태그를 찾는다
select(’.min’)min 클래스를 가진태그를 찾는다
select(’#min’)min id를 가진 태그를 찾는다
select(’a#min’)a태그중 id가 min인것
select(’a[href]’)a태그에서 href속성이 있는것을 찾는다
select(’a[href=”naver.com”]’)해당 속성 값이 있는 태그를 찾는다(href^,href$,href*)
href^으로 시작한다
href$중간에 포함한다
href*으로 끝난다

 

 

동적 페이지 스크래핑

동적 페이지 스크래핑에서 html을 가져오는 과정만 다르고 나머지는 똑같다

사전에 필요한 작업으로 크롬 드라이버를 사용해야한다

  1. pip3 install selenium 로 터미널에 설치
  2. 크롬 브라우저 버전에 맞는 드라이버를 설치한다

ChromeDriver - WebDriver for Chrome - Downloads

1
2
3
4
5
6
7
8
from selenium import webdriver
from bs4 import BeautifulSoup

driver = webdriver.Chrome(executable_path="드라이버 설치 경로")
url = '스크래핑할 사이트 url'
driver.get(url)

html = BeautifulSoup(driver.page_source, 'html.parser')

정적 페이지와 차이점은 requests 대신 selenium을 사용한점 빼고는 똑같아서 select를 사용하면 원하는 부분을 찾을 수 있다

또한 selenium은 페이지를 띄워서 사용하는것이기 때문에 매크로를 만들어서 더 복잡한 작업도 가능하다

만약 보안에 막혀서 스크래핑이 안돼도 selenium을 이용하면 해결할 수 있다

ActionChains를 통해서 클릭이나 텍스트 입력도 가능하다

만약 ImportError: cannot import name ‘webdriver’ from partially initialized module ‘selenium’ (most likely due to a circular import) 오류가 난다면 파이썬 파일이름이 selenium인지 확인한다 selenium이라면 다른 이름으로 변경 그럼 해결된다

 

 

예외의 경우

이번에 공지사항을 크롤링 하면서 위 두가지로 안된는 경우가 있었다

페이지의 요청이 두개 이상으로 되어있는 경우였는데 형태가 전체 틀을 먼저 가져오고 두번째 요청에서 내용을 가져오는 형태였다 위 방법 셀레니움 + beautifulsoup로 하면 첫번째 요청의 답인 페이지 틀만 가져오고 내용물인 content는 가져오지 못했다(요청을 한번 더 해야되서)

그래서 요청을 requests로 보내고 받아오는 형식으로 했다

만약 요청실패라고 뜬다면 헤더에 추가적으로 작성해서 요청을 보낸뒤 beautifulsoup로 문자열을 파싱 했다

This post is licensed under CC BY 4.0 by the author.