분산처리

airflow에서 크롤링(selenium) 할 경우 무한대기

aeongsseu 2023. 10. 17. 16:33

기존에 github action으로 crawler를 스케쥴링해놨었는데, github action의 cron은 표기보다 30분~한시간 랜덤으로 늦게 실행되어서(무료 서버다 보니) airflow로 옮기게 되었다.

 

그런데 airflow로 크롤링 시 자꾸 특정 코드 다음으로 안넘어가는 문제가 발생했다.

초기엔 webdriverManger.install()에서 해당 문제 발생

이에 webdriverManager가 아니라 직접 수동으로 webdriver를 다운 받아 사용했다.

하지만 다음번엔 driver.quit() 에서 문제 발생

크롤링에 로그인을 하고 다른 페이지로 리다이렉션하는 로직이 있어서 그런가 하여

headless 모드를 끄고 단순히 driver.get()이후 driver.quit() 하고 로그를 남기는 코드를 작성해 관찰해보니 브라우저 창은 정상적으로 꺼지는데 다음 코드로만 안넘어가게 되었다.(로그 메세지가 남지 않았다.)

 

이에 방법을 찾아보며 구글링으로 2일을 날리게 되었다 stackoverflow에도 질문해보고..
https://stackoverflow.com/questions/77299232/scheduling-crawler-by-airflow

 

scheduling crawler by airflow

import datetime as dt from pendulum import timezone from airflow import DAG from airflow.operators.python import PythonOperator import asyncio import time from dotenv import load_dotenv import os

stackoverflow.com

 

그러던중 나와 같은 현상을 겪는 사람이 더 있다는걸 알게되고 좀더 찾아보다가 아래와 같은 글을 봤다

https://careerly.co.kr/qnas/3991

 

Airflow로 selenium 덱 생성 시 driver.quit()을 하면 무한 running 현상

안녕하세요. 혼자 airflow로 연습을 하던 중 문제가 발생하여 질문드립니다. 하나의 테스크로 selenium을 이용한 크롤링 코드를 구현했습니다. 크롤링 코드...

careerly.co.kr

놀랍게도 나와 같은 현상을 겪었다는 글중에 답변이 달린건 하나도 없었다.

근데 딱 이글에만 결국 사람이 아닌 gpt4가 답변을 달아주었다.

그러면 왜 dag.test()랑 airflow dags test로는 정상작동했는지는 모르겠지만 일리가 있는 말이라 생각했다.

이에 더더욱 열심히 구글링을 해봤고 remote webdriver를 사용하면 된다는 말이있어 찾아보았다.

브라우저를 꺼도 브라우저 프로세스가 아직 실행 되고있는거로 인식한다면 외부에서 크롤링을 시키고 그 값만 가져온다음에 그 외부 서버는 종료해버리면 된다는 이론인 거다.

 

기존에 아래와같다면

remote webdriver를 사용하면 다음과 같이 된다.

글을 읽어보았다면 알 수 있듯이 사실 공식적인 이유와 해결방법은 아니다.
설명한 이론때문에 안되는거라면 말했듯이 dag.test()와 airflow dags test는 왜 적상 작동하는지 알 수 없고

라고 말하려던 중 나도 의문이 들어 gpt3에 한번 물어보았다. 그리고 답변은 아래와 같다.

remote webdriver의 사용법을 모르겠어서 계속 오류가 뜨는데 해결을 못하던 참이라 

스케쥴러에서 프로세스를 여러개 쓸 수 있는 방법이 있지 않을까 하여 다른 방법을 찾아보려했는데 위 방법도 시도 해봐야겠다.

해결방법은 정확히 알려주지 못했지만 나와 같은 문제를 겪는사람이 이유라도 알아갈 수 있으면 좋겠다.

 

이 글은 이후에 계속 수정 될 것이다.


2023-10-18

Operator가 실행되기 전에 외부와 통신해놓는 hook이란 것도 있다해서 시도해보니 똑같다.

그리고 Driver.quit()이 아니라 그냥 외부와 통신을 하면 멈추는거 같다. request.get()도 안된다.

from airflow import DAG
from airflow.operators.python import PythonOperator
import requests
import datetime as dt
from pendulum import timezone


def fetch_data():
    try:
        response = requests.get('https://api.example.com/data')
        data = response.text
        print(data)

    except Exception as e:
        raise Exception(f"Error fetching data: {str(e)}")


dag = DAG('example_dag',
          start_date=dt.datetime(2023,10,13,
                                 tzinfo=timezone("Asia/Seoul")),
          catchup=False,
          schedule_interval='@daily')

fetch_data_task = PythonOperator(
    task_id='fetch_data',
    python_callable=fetch_data,
    dag=dag
)

위 코드 역시 print(data)까지 가지 않고 에러 메세지도 뜨지 않고 running상태에서 멈춰있다.

 

 

결국 그냥 크롤링 코드를 따로 빼고 해당 파일을 bashoperator 사용해서 실행시키니까 성공했다.

 


2023-10-19

airflow discussion에 질문을 올려 놓았다.

https://github.com/apache/airflow/discussions/35049

 

external communication in pythonoperator · apache/airflow · Discussion #35049

same question on stackoverflow : https://stackoverflow.com/questions/77299232/scheduling-crawler-by-airflow I was build a simple crawler pipeline So I use Selenium with Python Operator At first I u...

github.com