ターゲット層
何かを収集したい人。作業を自動化したいめんどくさがりやな人。
自動操作、スクレイピングに興味がある人。
記事を書く理由
最近、pythonを触っていなかったから。学生の頃、主にpythonで開発していたが、今年社会人になり触る機会が減ったため久しぶりに触ろうと思い、この記事を書こうと思った。なぜ、スクレイピングかというと、学生時代コロナ禍で学校の登下校の登録がGoogle formで提出する必要があった。それの自動化が印象深かったため、自動操作(Selenium, chromedriver)を含めたスクレイピングを書くことにした。
全体的な進め方
まずは環境について。簡易に試してもらいたいためGoogleが機械学習を学ぶために無料て提供されているGoogle Colaboratoryを使う。イメージとしてはJupyterのweb版みたいな感じ。Googleアカウントを持っていれば使用できる。
その後Yahoo!さんでスクレイピングをやっていく。
順序
- Google Colab を開く https://colab.research.google.com
- yahooニュースのタイトルとリンクを取得(BeautifulSoupを使用)
- yahooニュースのタイトル詳細と詳細を取得(selenium, chromedriverを使用)
yahooニュースのタイトルとリンク取得
# 日本語フォントインストール
!apt install fonts-ipafont-gothic
# Seleniumインストール
!pip install selenium
# chromedriverインストール
!apt update
!apt install chromium-chromedriver
!cp /usr/lib/chromium-browser/chromedriver /usr/bin
# ライブラリのインポート
from urllib.request import urlopen
from bs4 import BeautifulSoup
# 取得したい要素のcss selector
target_css_selector = '#tabpanelTopics1 > div > div._2jjSS8r_I9Zd6O9NFJtDN- > ul > li > article > a'
# DOMの取得
data = urlopen("https://www.yahoo.co.jp/")
soup_parsed_data = BeautifulSoup(data, 'html.parser')
# 要素の取得
get_title_list = soup_parsed_data.select(target_css_selector)
for get_elem in get_title_list:
get_title = get_elem.find('span').contents[0]
get_link = get_elem.attrs['href']
print(get_title)
print(get_link)
yahooニュースのタイトル詳細と詳細を取得
# ライブラリのインポート
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# ブラウザをheadlessモード(バックグラウンドで動くモード)で立ち上げ
options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
driver = webdriver.Chrome('chromedriver',options=options)
driver.implicitly_wait(10)
def main():
"""
yahooニュースのタイトル詳細と詳細を取得
"""
# Yahooにアクセス
url = "https://www.yahoo.co.jp/"
driver.get(url)
## ここが少し危険(遷移が完了する前に下の処理が流れる可能性があるが、ここで落ちたことはない)
# 記事の数を取得
tag_title_list = driver.find_elements(by=By.CSS_SELECTOR, value="#tabpanelTopics1 > div > div._2jjSS8r_I9Zd6O9NFJtDN- > ul > li > article > a")
title_length = len(tag_title_list)
for index in range(title_length):
# 個別に要素を取得
title_css_selector = f"#tabpanelTopics1 > div > div._2jjSS8r_I9Zd6O9NFJtDN- > ul > li:nth-of-type({str(1+index)}) > article > a"
tag_title = wait_get_element(title_css_selector)
# ニュースページへ遷移
tag_title.click()
get_news_text(url)
def get_news_text(url):
"""
ニュースページからニュース詳細ページへ遷移
テキストの取得
"""
# ニュース詳細ページへ遷移
tags_2 = wait_get_element("#uamods-pickup > div.sc-muxYx.kNLljN > a")
tags_2.click()
# テキストの取得
title = wait_get_element("#uamods > header > h1").text
text = driver.find_elements(by=By.CSS_SELECTOR, value="#uamods > div.article_body.highLightSearchTarget > div > p")
print('==============タイトル詳細')
print(title)
print('==============詳細')
for text_line in text:
print(text_line.text)
# トップページに戻る
driver.get(url)
def wait_get_element(css_selector):
"""
要素が検出できるまで待機
要素を取得
"""
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, css_selector))
)
return element
# 実行
main()
やっていることは、トップページでクリック、ニュースページでクリック、ニュース詳細ページで取得。
画面的には トップ⇨ニュース⇨ニュース詳細⇨トップ⇨ニュース⇨ニュース詳細⇨トップ...の繰り返し。
気づき
- getし直すと、WebElementオブジェクトが変わる。
<selenium.webdriver.remote.webelement.WebElement (session="aa3722e44bea11244055f625317e2b63", element="d7a9d819-e79c-414e-9312-1055145e2c46")>
<selenium.webdriver.remote.webelement.WebElement (session="aa3722e44bea11244055f625317e2b63", element="7a60957e-57c1-467b-9c07-dc23b5154db8")>
- このコードを書いている時、地震速報がきてエラーが出た。(速報系はテンプレが違うのかも)
- chromeからcss selectorをコピーした際、nth-childが入っている場合、nth-of-typeに書き換える必要がある。
- Yahoo!ファイナンス掲載情報の自動取得(スクレイピング)は禁止
その他、気づき、指摘があればコメントください。
参考資料
- 待機時間 https://www.teru2teru.com/python/selenium/do-not-time-sleep/#outline__2
- 開発環境準備 https://i-doctor.sakura.ne.jp/font/?p=46745
- Selenium https://www.seleniumqref.com/api/webdriver_gyaku.html
- nth-childとnth-of-type https://system.hot-maker.com/73/
- chromedriverダウンロード https://chromedriver.chromium.org/downloads