본문 바로가기
Tools

라즈베리파이 4 과 파이썬, Firefox, Selenium - CLI

by Calvin H. 2023. 11. 17.

소개

라즈베리파이 4 에서 Firefox 브라우저를 Selenium 으로 실행한 내용에 대해 정리하는 글입니다.

 

깃헙 주소:

- https://github.com/ankylos/ankylos-crawler

 

도커 허브 주소

- https://hub.docker.com/repository/docker/lambrosopos/ankylos-scraper/general

 

물론, 이미지를 실질적으로는 ArgoCD 를 통해서 띄우기 위한 별도 차트 레포는 비공개로 되어 있지만, 추후에 정리되면 해당 레포에 관한 부분도 정리해보도록 하겠습니다.

 

 

들어가기 전에...

실제 글을 시작하기 전에 더 명확한 이해를 위한 맥락을 조금 더 공유해보도록 하겠습니다.

 

크롤링과 스크레이핑

 

일단, 크롤링 서버라고 부르고 있지만, 실질적으로는 스크레이핑 용도의 서버로, 네이버 음식점의 url 이 주어지면 해당 주소를 통해 메뉴를 데이터베이스에 저장하는 기능 하나를 가지고 있습니다. 그 이유는 크롤링 서버와 스크레이핑 서버를 별도로 분리할 예정이라 그렇습니다.

 

  • 크롤링 서버는 말 그대로 네이버 음식점들의 주소와 요청에 대한 응답들을 저장하고 계속해서 새로운 음식점 주소들을 저장합니다.
  • 스크레이핑 서버는 크롤링 서버에서 수집한 정보들을 바탕으로 내용들을 파싱하고 추출해서 데이터베이스에 저장합니다.
  • 크롤링 서버와 스크레이핑 서버가 소통할 수 있게 메세지 큐가 클러스터 내에서 어느 주소들을 처리해야 할지 관리합니다.

클러스터

Raspberry Pi 4 에는 Debian GNU/Linux 11 (bullseye) 64 bit 이 설치되어 있습니다 (`cat /etc/*release`). 이 위에 k3s 가 실행되고 있고 CD 를 위한 ArgoCD 가 argocd 네임스페이스에 실행되고 있습니다. 사용할 때에는 보통 port-forwarding 으로만 잠깐 연결해서 사용합니다.

 

아쉽게도 Raspberry Pi 4 의 메모리가 적어서 (4GB) 최소한의 리소스를 사용하는 것을 목표로 하고 있습니다. Selenium 과 같은 프로세스를 실행하기에는 살짝 버겁기도 해서 조만간 다른 흐름으로 바꿀 예정입니다.

 

CI/CD

Github Actions 가 무료로 제공되어서 이를 주로 사용하고 있습니다. Test 하는 것과 배포하는 것 다 여기서 진행을 하고 있습니다.

 

Github 레포에서 Github Action 을 통해서 Release 가 되는 경우 도커 허브에 이미지를 배포하는 방식으로 이미지를 관리하고 있습니다. 이렇게 배포된 이미지는 2 개의 태그가 붙습니다.

  • latest
  • github commit sha

 

그리고 k3s 에 배포하기 위한 별도 차트 레포가 있어서 해당 레포의 태그만 업데이트 해주면 ArgoCD 에서 자동으로 이를 클러스터에 최종적으로 배포해주고 있습니다.

 

다만 지금 구조에서는 한 레포에 크롤링, 스크레이핑 다 넣을려고 했는데 Release 는 카테고리를 주기 힘들어서 별도의 레포로 관리를 할까 고민중에 있습니다. 어차피 크롤링 서버는 Go 로 제작할 예정이라 코드가 다르긴 하지만 레포가 많아지는 것에 대한 불편함이 있어서 하나로 생각하고 있었는데, microservice 구조에 좀 더 자연스럽게 별도로 진행할 것 같습니다.

 

 

Firefox 설치하기

이 글에서 설치하는 버전은 Firefox ESR (Extended Support Release) 입니다. 간단하게는 데이터 보호에 조금 더 신경 썼으며 기업에서 사용하는 목적으로 배포되는 버전으로 안정성을 높였습니다.

 

먼저 다음과 같이 패키지 목록을 업데이트 합니다.

 

$ sudo apt update

 

그리고 `firefox-esr` 을 설치해줍니다.

$ sudo apt install -y firefox-esr

 

 

설치가 완료되면 다음과 같이 `Firefox` 를 찾을 수 있는지 확인해줍니다.

 

$ which firefox

 

그러면 다음과 같이 뜨면 설치가 잘 된 것으로 볼 수 있습니다.

/usr/bin/firefox

 

 

Geckodriver

다음은 geckodriver 설치입니다. Geckodriver 는 쉽게 말해서 selenium 이 상호작용할 수 있도록 도와주는 역할을 하고 있습니다. Selenium 에서 Firefox 와 바로 소통하지 않고 해당 브라우저 드라이버를 통해서 상호작용하는 것이죠. 보통은 코드를 통해서 웹 브라우저에 접근을 하지 않기 때문에 해당 드라이버는 설치가 안되어 있는 경우가 많습니다.

 

Geckodriver 는 Github 릴리즈에서 원하는 릴리즈 버전을 다운로드 받을 수 있습니다.

- https://github.com/mozilla/geckodriver/releases

 

Releases · mozilla/geckodriver

WebDriver for Firefox. Contribute to mozilla/geckodriver development by creating an account on GitHub.

github.com

 

라즈베리파이는 ARM 기반 아키텍쳐이고 설치된 운영체제는 64비트라서 다음과 같이 `linux` 와 `aarch64` (ARM64) 가 들어있는 `tar.gz` 을 선택하시면 됩니다.

 

CLI 에서 다운로드 하려면 해당 링크를 복사해 `wget` 을 이용해 다음과 같이 받아줍니다.

$ wget "https://github.com/mozilla/geckodriver/releases/download/v0.33.0/geckodriver-v0.33.0-linux-aarch64.tar.gz"

 

 

위에서는 `v0.33.0` 을 다운로드 하지만 필요한 다른 버전을 하셔도 괜찮습니다.

 

다운로드가 되었다면 `tar.gz` 으로 압축되어 있는 부분을 해제해줘야 합니다.

 

$ tar -xvf geckodriver-v0.33.0-linux-aarch64.tar.gz

 

`tar` 명령어가 궁금하시다면 `man tar` 로 확인해보셔도 좋습니다. 위에서는 간단하게 `-xvf` 를 사용했는데 의미는 다음과 같습니다.

  • v: Verbose 로 로그를 다 보고 싶을 때 추가합니다.
  • f: Archive File 을 사용한다는 뜻으로 파일을 전달해준다는 뜻입니다. 파일을 넘겨준다는 신호를 보냅니다.
  • x: Extract 로 압축된 파일에서 압축 해제하라는 뜻입니다.

압축 해제를 하게 되면 `geckodriver` 라는 실행가능한 파일이 생깁니다. 해당 파일을 어디에 놓아도 상관이 없긴 한데, PATH 를 통해서 찾을 수 있는 경로에 포함해 줍니다.

 

PATH 가 궁금하다면 `echo $PATH` 를 통해서 확인하고 출력된 디렉토리 중에 넣어주시면 됩니다.

 

저는 `/usr/local/bin` 에 추가해주겠습니다.

 

먼저 옮겨줍니다. `/etc/` 디렉토리는 root 에 있어서 sudo 가 필요합니다.

$ sudo mv ./geckodriver /usr/local/bin/geckodriver

 

이제 geckodriver 가 실행 가능하도록 모드를 추가해주겠습니다.

$ sudo chmod +x /usr/local/bin/geckodriver

 

Selenium

Selenium 설치

자 이제, Selenium 을 설치해보겠습니다.

 

파이썬으로 설치를 해보겠습니다. Pip 을 사용하면 다음과 같이 설치할 수 있습니다.

$ python3 -m pip install selenium

 

 

Selenium Firefox 사용하기

이제 드디어 selenium 을 통해 Firefox 브라우저를 실행해보겠습니다.

from selenium import webdriver

options = webdriver.FirefoxOptions()
options.add_argument("--headless")

service = webdriver.FirefoxService(executable_path="/usr/local/bin/geckodriver")

driver = webdriver.Firefox(options=options, service=service)

driver.get("https://www.google.com")

 

 

options

위에서 `options` 를 통해서 Firefox 옵션을 설정할 수 있습니다. 여기에서는 `-headless` 를 통해서 브라우저의 GUI 를 실행하지 않는 옵션입니다. 옵션을 추가하지 않게 되면 실제로 웹 브라우저를 실행하는 것과 동일하게 새로운 브라우저 창이 열리게 됩니다.

 

service

`FirefoxService` 를 통해서 geckodriver 경로를 정할 수 있습니다. 별도로 정해지지 않는다면 `geckodriver` 를 사용하게 됩니다. 따라서 PATH 에 포함되어서 실행될 수 있는 상태로 추가해놓고 실행가능한 상태여야 합니다.

 

driver

브라우저를 실행하는 부분인 `Firefox` 입니다. 앞서 만든 options 와 service 인스턴스들을 인자로 넘겨주면 Firefox 브라우저를 실행하게 됩니다.

 

Selenium 브라우징

Selenium 드라이버를 실행한 뒤에는 다음과 같이 사용할 수 있습니다.

 

# 웹페이지 방문
driver.get("https://www.google.com")

# HTML 소스 읽기
driver.page_source

# Javascript 실행하기
driver.execute_script("return window")

 

가져온 정보들로 이제 필요한 작업을 실행하면 됩니다.

 

정리

이번 글을 통해서 ARM 64 기반 Raspberry Pi 4 에서 Firefox 브라우저를 selenium 을 통해서 실행하게 되는 과정을 살펴보았습니다. 특히 크롤링, 스크레이핑을 위해서 자바스크립트를 실행해야하는 웹페이지 (SPA 기반) 을 탐색해야 할 때 제일 편한 방법인 것 같습니다.

 

물론, 성능적인 측면에서는 느려서, 가능하다면 병렬처리로 비동기 HTTP 요청들을 사용하는 것을 최대한 사용하는 것도 중요하다고 생각합니다. 특히 자바스크립트를 포함해 여러 리소스 등을 다 받게 된다면 몇 초는 필요하게 되어서 최대한 자제하는 것을 추천드립니다.

'Tools' 카테고리의 다른 글

k3s 라즈베리파이 클러스터 ArgoCD 설치  (0) 2023.10.12
유용한 Vim Plugins  (0) 2022.06.01
Intro to Scrapy  (0) 2022.06.01
iTerm과의 고군분투쓰  (0) 2022.05.31
Atom text-editor  (0) 2022.05.30