야구 데이터를 지속적으로 얻기 위해서 http://www.statiz.co.kr/main.php 사이트에서 경기 정보를 크롤링하여 데이터를 적재하는 DAG를 작성하는과정중 예상치 못한 문제가 발생했다.
크롤링을 제대로 해본적이 없어서 이것 저것 찾아가면서 찾은 방법중 하나는 selenium 모듈을 이용한 방식이었다.
모듈을 import 한 뒤 크롬 웹드라이버를 이용해서 크롤링 샘플 코드를 작성했고 정상적으로 작동했다.
from bs4 import BeautifulSoup
import pandas as pd
from selenium import webdriver
import re
from selenium.webdriver.common.by import By
from datetime import datetime
import pymysql
from sqlalchemy import create_engine
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')
chromeDriver = webdriver.Chrome('chromedriver',chrome_options=chrome_options)
chromeDriver.get("http://www.statiz.co.kr/schedule.php")
html = chromeDriver.page_source
bsObject = BeautifulSoup(html, 'html.parser')
# 날짜정보 받아오기
now = datetime.now().strftime("%Y-%m-%d")
now = '2023-04-08'
init_url = str(bsObject.find_all('table', {'class' : 'table table-striped table-bordered'})).split(f'boxscore.php?date={now}&')[-5:]
이 코드를 DAG형식으로 바꿔서 실행을 시켜봤더니 에러가 발생했다.
- chromedriver error
local환경에서는 단순하게 크롬 드라이버를 다운받은 후 경로를 지정해줬는데
Docker는 Linux기반이라 드라이버 파일이 의미가 없었다.. 너무 무지성으로 진행한 탓..
그래서 Airflow 공식이미지에 크롬 드라이버를 다운로드 받는 커스텀 Dockerfile을 생성한 후
# 크롬드라이버 설치를 위한 Dockerfile
FROM apache/airflow:2.5.2
USER root
WORKDIR /usr/src
RUN apt-get update && apt-get install -y sudo wget
RUN apt install wget
RUN apt install unzip
RUN wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
RUN apt -y install ./google-chrome-stable_current_amd64.deb
RUN wget -O /tmp/chromedriver.zip http://chromedriver.storage.googleapis.com/` curl -sS chromedriver.storage.googleapis.com/LATEST_RELEASE`/chromedriver_linux64.zip
RUN mkdir chrome
RUN unzip /tmp/chromedriver.zip chromedriver -d /usr/src/chrome
USER airflow
WORKDIR /opt/airflow
RUN pip install --upgrade pip
COPY requirements.txt ./
RUN pip install -r requirements.txt
# docker build . -t "airflow_server"
이 이미지를 가지고 크롤링 DAG를 실행시켜봤다.
- timeout error
selenium.common.exceptions.TimeoutException: Message: timeout: Timed out receiving message from renderer: 299.918
이상하게도 로컬환경에서 크롤링을 했을때는 매우 빠른 속도로 진행되었는데 Docker환경에서 크롤링을 하니 타임아웃이 발생했다.
원인분석
- timeout 세팅 시간 변경
우선 timeout 에러이기 때문에 set_page_load_timeout(1000) 설정으로 1000초 동안 크롤링을 시도해봤다.
결과 => timeout 에러 발생
- 해당 사이트의 문제
구글링을 통해 찾아보니 구글이나 네이버는 정상적으로 크롤링이 되는데 다른 사이트들은 안되는 경우가 있다해서
네이버 크롤링을 시도해봤다.
결과 => 정상적으로 크롤링이 되었다.
- 드라이버 옵션 문제
크롬 드라이버의 문제는 없다고 가정하고 구글링을 통해 옵션을 변경해봤다.
결과 : timeout 에러 발생
해결
timeout 세팅시간을 늘려도 에러가 나기 때문에 selenium이 아닌 urllib.request 모듈을 사용하는게 더 나을 것 같아서 request방식으로 진행했다.
request방식으로 진행하니 페이지 크롤링이 정상적으로 되었다.
selenium 방식으로 크롤링이 되지 않았던 이유는 정확히 파악하지는 못했지만
가상환경의 proxy server가 사이트에서 차단되는게 아닐까싶다.
프로젝트를 진행하는데 가장 중요한 데이터를 받아오는 과정인데 에러가 나서 4시간동안 삽질을 했다...
결과적으로 request 방식으로 크롤링이 되서 다행이다.
'Docker' 카테고리의 다른 글
Docker Swarm 이란 무엇인가? (0) | 2023.09.07 |
---|---|
Docker 환경에서 크롤링하기(동적 웹) (0) | 2023.06.30 |
Docker - Airflow (0) | 2023.04.12 |
Docker 환경 구성 (2) (0) | 2023.04.11 |
Docker 환경 구성 (1) (0) | 2023.04.03 |