파이썬 혼자놀기 패키지 개발일지 1

(썸네일은 야통이다. youtube hahaha)

웹 이미지 크롤링 하기

1. venv란?

venv는 Virtual Environment의 약자로 파이썬의 경우 프로젝트 마다 라이브러리를 저장하는 폴더를 별도로 지정한다. 해당 폴더의 이름이 바로 venv이다. 프로젝트마다 라이브러리가 독립되기 때문에 버전의 호환등을 신경 쓸 필요가 없다.

2. dload

dload는 path로 부터 심플하게 내용을 다운로드 해주는 패키지로 다양한 옵션으로 상황에 맞는 편의를 제공 해주기도 하고 심플하게

import dload
dload.save(URL)

위와 같이 입력만 하면 프로젝트 폴더에 바로 URL내용이 다운로드 된다.
dload 개발자 깃헙

3. selenium

selenium은 웹브라우저 자동화 도구로 파이썬으로 처음 접해본 것인데 파이썬 말고도 다른 언어에서도 지원하는 것 같다.
이번에는 크롬 브라우저를 자동으로 열고 닫고 하는 기능으로 썼다.
selenium 개발자 깃헙

4. BeautifulSoup

현재 버전은 bs4로 html을 파싱하는 강력한 기능의 패키지이다.
자세한 내용은 pypi.org 문서에 잘 설명되어있다.
한국어로도 문서화가 되어있다.

5. 웹 이미지 크롤링

이제 dload, selenium, BeautifulSoup 3가지 라이브러리를 통해 웹 검색 결과물을 한꺼번에 크롤링 해서 다운로드 하는 코드를 짤 수 있다.

# 1
import dload
from bs4 import BeautifulSoup
from selenium import webdriver
import time

# 2
driver = webdriver.Chrome('./chromedriver') # 웹드라이버 파일의 경로
driver.get("https://search.naver.com/search.naver?where=image&sm=tab_jum&query=%EC%95%BC%ED%86%B5%EC%9D%B4")
time.sleep(2) # 5초 동안 페이지 로딩 기다리기

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


# 3
tumbnails = soup.find_all(class_="thumb")

for index, tumbnail in enumerate(tumbnails):
    img = tumbnail.find("img")['src']
    if ~img.find('http'):
        path = 'img/{0}.jpg'
        dload.save(img, path.format(index))

driver.quit()
  1. 앞서 설명한 라이브러리 패키지를 불러왔다
  2. selenium을 이용해서 크롬을 열고 해당 주소로 이동하고 .quit()를 통해 크롬을 닫는다.
  3. 이제 soup를 통해서 이미지 주소를 파싱해야 하는데 네이버에서 해보았다.
    위 코드는 html소스에서 thumb 클래스 안에 있는 내용을 모조리 tumbnails에 넣었고
    for-in 안에서 다시 img를 찾아 'src'로 시작하는 것만 img에 대입했다.
    그런데 이 과정에서 이런 코드가 딸려와서
    "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
    dload가 알아서 걸러 다운로드 받인 했는데 에러가 발생해서 필터링 할 방법을 찾던 중 http를 포함하지 않는 경우만 검색했더니 이게 걸러졌다. 왜 그런지 이유는 도대체 모름

원하는 부분을 파싱할때 지금같은 경우는 원하는 클래스를 찾았는데
다른 방법도 있다.

soup.select()를 이용하는 방법인데 해당 소스의 selector 전달해주면 일일이 find로 거르지 않아도 바로 소스를 찾을 수 있다.

selector의 경우는 #main_pack > section > div > div.photo_group._listGrid > div.photo_tile._grid > div:nth-child(1) > div > div.thumb > a > img
이러한 코드가 복사되었는데
네이버의 경우는
div.photo_group._listGrid이 div아래에 사진들이 모두 묶여있었다. 그래서 soup.select에 전달할 때

soup.select('#main_pack > section > div > div.photo_group._listGrid > div.photo_tile._grid > div > div > div.thumb > a > img')

이렇게 수정해서 넘겼더니 모든 img 라인을 파싱할 수 있었다.

좋은 웹페이지 즐겨찾기