Python/알면 쓸모있는 잡다한 코드

selenium chrome webdriver crawling

joannekim0420 2023. 8. 24. 17:16
728x90

selenium 으로 web crawling 방법

chrome web driver 버전 오류 해결방법

 

크롤링은 주피터 노트북으로 하는게 편했다..

!pip install pyvirtualdisplay
!pip install webdriver_manager
from selenium import webdriver
import time
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.options import Options
from pyvirtualdisplay import Display
from selenium.webdriver.common.by import By


chrome_options = Options()  
chrome_options.add_argument("--headless")  
chrome_options.add_argument("--start-maximized")
chrome_options.add_argument("--start-fullscreen")
chrome_options.add_argument("--no-proxy-server")
chrome_options.add_argument("--proxy-server='direct://'");
chrome_options.add_argument("--proxy-bypass-list=*");
chrome_options.add_experimental_option("detach",True)
chrome_options.add_experimental_option("excludeSwitches",["enable-logging"])


# browser = webdriver.Chrome(executable_path=chromedriver,options = chrome_options)
driver = webdriver.Chrome(service =Service(ChromeDriverManager().install()), options=chrome_options)

필요한 패키지들 import 하고 driver 지정. 

 

driver.implicitly_wait(5)
language = ['ar','bg','da','el','en','et','id','ja','ko','tr','vi']
# for language in languages:
language = "tr"

URL = f"https://{language}&flags=f" #크롤링 하고자 하는 페이지 URL 주소

driver.get(URL)

보통 크롤링을 한다는 것은 방대한 양의 이미지나 텍스트 파일을 일일이 내가 직접 저장하기엔 번거롭기 때문에 자동화 하겠다는 것이다. 

예시로 11개 언어마다 페이지가 있는 주소를 하나하나 들어가서 크롤링 한다면, 

driver.get(URL)로 해당 페이지를 가져온다. 

 

def get_jpg_names(driver):
    jpg_urls = []
    for i in range(3, 684):#817-da,544-el,688-en, 783-et, 857-id, 845-ja, 892-ko, 684-tr, 872-vi
        selector = "#content > div > table.files.enable_read > tbody > tr:nth-child("+str(i)+") > td:nth-child(8) > a"
        elements = driver.find_element(By.CSS_SELECTOR, selector)
        jpg = elements.get_attribute('href')
        jpg_urls.append(jpg)
    return jpg_urls

driver.find_element()

실제 필요한 부분의 CSS_SELECTOR 를 driver가 찾고 가져와야 하는데..

앞서 from selenium.webdriver.common.by import By 를 import 해줬기 때문에, 

driver.find_element(By.CSS_SELECTOR, selector) 이면 쉽게 찾을 수 있다. 

 

내가 원하는 selector는 찾기

F12 버튼을 누르면 옆 페이지를 통해서 내가 가져오고자 하는 부분을 구조적으로 찾을 수 있다. 

나는 저 이미지를 갖고오고 싶기 때문에 우선 이미지 클래스에 해당하는 CSS selector를 찾으려면 해당 부분에서 우클릭한다.

  • 우클릭 → copy → copy selector 

만약 여러 이미지에 대해서 크롤링을 하는데 특정 변수만 바뀐다면, (여기서는 selector 에 str(i) 부분에 해당)

변수 처리해주고 원하는만큼 for문을 돌면서 최종적으로 img url 을 get_attribute 'href'로 가져온다. 

 

해당 이미지 url들을 나는 리스트에 저장해서 전달하겠다. 

 

 

import os 
import urllib.request
from urllib.request import urlopen
from PIL import Image
    
img_folder = './image_pixels/'+language
if not os.path.isdir(img_folder) : 
    os.mkdir(img_folder)
    
for i, url in enumerate(list_of_urls):
    name = url.split("/")[-1]
    print(i)
    
    img_flag = f'./image_pixels/{language}/{name}.jpg'
    if not os.path.exists(img_flag) : 
        print(name)
        img = Image.open(urlopen(url))
        img.save(img_flag)
#         urllib.request.urlretrieve(url, img_flag)

1. urllib.request.urlretrieve(url, img_flag) 
→ url에 해당하는 이미지를 지정된 경로와 이미지의 이름의 img_flag 로 저장하겠다는 것인데.. 

저장은 잘 되지만 시간이 지나면 timeout error가 발생한다... 

2. img = Image.open(urlopen(url))

    img.save(img_flag)

→ urllib.request 의 urlopen 을 하고 이후에 Image.open, img.save로 저장하는 방법. 

time out error 없이 잘 이루어진다. 

 

 

chrome web driver 버전 오류 해결방법

여러 글들을 확인해본 결과 microsoft edge로 하면 잘 된다, 버전이 안 맞는 것이다 , 등 여러 이유가 있었는데

나 같은 경우는 microsoft edge로 하나 chrome 으로 하나 똑같은 문제가 발생했고

버전이 안 맞는 경우였다. 

 

WebDriverException: Message: unknown error: net::ERR_CONNECTION_REFUSED

에러가 발생했을 때, 내 버전은 (Session info: headless chrome=114.0.5735.199)

 

https://chromedriver.storage.googleapis.com/index.html 사이트에 들어가서 

114.0.5735.16 chrome web driver 버전의 win32 다운받고 다시 install 했더니 ERR_CONNECTION_REFUSED 는 잘 해결 됐다.