経緯
スクレイピング対象のwebページが動的(javascript)に生成するページたった。
それを解決するためSeleniumの知識が必要そうだった。
実際に動かすまでに時間がかかったので備忘録として残す。
目的
M1 macでdocker for macで立ち上げたseleniumコンテナを立ち上げる
seleniumコンテナを使って、動的に生成されるNHKニュースサイトの一覧を取得する
前提
- PC: M1 Macbook pro 14インチ 2021
- OS: macOS 12.6
- 言語: python3.9.6
Seleniumとは
Webアプリケーションをテストするためのフレームワーク
Webブラウザを自動操作することができ、動作検証することができる。
必要なもの
- Webブラウザ
- Chrome,Edge,Sarariなど
- WebDriver
- ブラウザを操作するためのAPIを公開するモジュール。ブラウザとバージョンをあわせる必要がある
- Selenium
- WebDriverと通信し、プログラムからブラウザを操作するライブラリ
ローカルでやろうとすると、
・検証したいWebブラウザをインストール
・Webブラウザのバージョンに合わせてWebDriverをインストール
があるので面倒。
公式Dockerは WebDriver が動作するバージョンの組み合わせでインストール済みなのでDockerを使うのがおすすめ
dockerでseleniumコンテナを構築する
公式ドキュメント によると、
https://github.com/SeleniumHQ/docker-selenium
For experimental docker container images, which run on platforms such as the Mac M1 or Raspberry Pi, see the >community driven repository hosted at seleniumhq-community/docker-seleniarm. These images are built for three separate architectures: linux/arm64 (aarch64), linux/arm/v7 (armhf), and linux/amd64.
m1 macは seleniumhq-community/docker-seleniarm リポジトリを参考にしてと言われているので、
https://github.com/seleniumhq-community/docker-seleniarm のドキュメントを参考にする
現時点でArm用のChromeはないので、Arm用に構築されたChromiumコンテナを立ち上げる
% docker run --rm -it -p 4444:4444 -p 5900:5900 -p 7900:7900 --shm-size 2g seleniarm/standalone-chromium:latest
Seleniumコンテナを使ってスクレイピングを試す
NHKニュースサイトのアクセスランキングから、記事のタイトル一覧をコンソールで表示する。
アクセスするURL: https://www3.nhk.or.jp/news/ranking/access.html
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
print("**NHKニュースサイトから取得開始します...**")
try:
# Chromeのオプションを設定する
options = webdriver.ChromeOptions()
# 画面を描画しない
options.add_argument('--headless')
# Selenium Server に接続する
driver = webdriver.Remote(
command_executor='http://127.0.0.1:4444/wd/hub',
options=options,
)
# NHK ニュースランキングにアクセス
driver.get("https://www3.nhk.or.jp/news/ranking/access.html")
# 定義済みの条件で待機する(最大20秒)
WebDriverWait(driver, 20).until(
# 指定したページ上の要素が読み込まれるまで待機
EC.presence_of_element_located((By.TAG_NAME, "em"))
)
# HTMLを文字コードをUTF-8に変換してから取得
html = driver.page_source.encode('utf-8')
# 取得したhtmlをBeautifulSoupで解析
soup = BeautifulSoup(html, "html.parser")
# 記事一覧を表示している要素だけに絞る
section = soup.find("section", class_="content--items")
# em要素すべてを摘出する
emlist = section.find_all("em")
for em in emlist:
print(em.text)
except Exception as e:
print("**エラーが発生しました**")
print(e)
finally:
print("**NHKニュースサイトから取得終了します...**")
# ブラウザを終了する
driver.quit()
Docker Seleniumのwebブラウザ操作を表示する
5900ポートでVNCサーバに繋げられる。
Finderを開いて command + k
vnc://localhost:5900 // パスワードは secret
↑のコードで動かしたいなら
options.add_argument('--headless')
をコメントアウトする。
参考
Docker+Selenium ServerでWebブラウザ自動操作環境を作る
Docker Desktop for Apple siliconでseleniumを使う
10分で理解する Selenium
[Python]Seleniumでのwaitの方法とは?様々な待機方法を紹介します!
docker-selenium 使って見た