Contents
⚓ 1. はじめに
Udemyのトライアルにて、「PythonによるWebスクレイピング〜入門編〜 業務効率化への第一歩」という講座を受講した。
そこで学んだ内容を、以下の3つの記事で共有したい。
- Python + Seleniumでウェブスクレイピング Vol.1 - シンプルなDOM -(本投稿)
- Python + Seleniumでウェブスクレイピング Vol.2 - より複雑なDOM -
- Python + Seleniumでウェブスクレイピング Vol.3 - 画像収集 -
ソースコード全体を参照したい場合は、「5. ソースコード」](https://oasist-blog-ja.hatenablog.jp/entry/web_scraping_in_python_selenium_vol1#contents-5)に飛んで頂きたい。
⚓ 2. 成果物
講師情報 - Webスクレイピング入門から講師情報を取得し、CSVファイルにエクスポートする。
項目 | 値 | |
---|---|---|
0 | 講師名 | 今西 航平 |
1 | 所属企業 | 株式会社キカガク |
2 | 生年月日 | 1994年7月15日 |
3 | 出身 | 千葉県 |
4 | 趣味 | バスケットボール、読書、ガジェット集め |
⚓ 3. 実装
⚓ 3-1. ログイン
初めに、Google Chromeを立ち上げて特定のURLにアクセスする必要がある。
この一連の処理は TextExtractor
クラスのインスタンス生成時に呼び出される。
コンストラクタはURL(https://scraping-for-beginner.herokuapp.com/login_page)を引数に取る。
get
メソッドを使うことで指定したURLにアクセス出来るが、あらかじめ webdriver
をインポートするのを忘れないように。
def __init__(self, url): self.chrome = webdriver.Chrome(executable_path="../exec/chromedriver.exe") self.chrome.get(url)
TextExtractor#login
はユーザー名とパスワードを引数に取る。
インスペクターを用いれば #username
、#password
、#login-btn
をDOM中に見つけることができる。



webdriver
によって、特定のID要素を見つけるための find_element_by_id
メソッドが利用可能だ。
また、必要なパラメータを入力する send_keys
メソッドや、ボタンのクリック操作を行う click
も利用することができる。
def login(self, user_name, pwd): username = self.chrome.find_element_by_id("username") username.send_keys(user_name) password = self.chrome.find_element_by_id("password") password.send_keys(pwd) login = self.chrome.find_element_by_id("login-btn") login.click()
ログイン完了後、講師情報のテーブルを参照することができる。
⚓ 3-2. 情報取得
th
要素からはキーを、td
要素から値を取得する。
find_elements_by_tag_name
メソッドを使うと、特定タグの要素のリストを得ることができる。
※ find_element_by_tag_name
は特定タグの最初の要素を返す。
特定のタグ要素の配列を得たら、以下の手順で各要素からテキスト情報を取り出す。
- 各要素のテキスト情報を挿入するための空のリストを生成する。
for
文でループを回し、各要素の.text
でテキスト情報を取り出す。- テキスト情報にエスケープシーケンスが含まれている場合、特定の文字列に置換する。
- 手順1で生成したリストにテキスト情報を追加する。
最後に キーと値を返す。
今回はユニットテストを分かりやすくするために {キー: 値}
のディクショナリーも返している。
TextExtractor#get_lecturer_info
def get_lecturer_info(self): ths = self.chrome.find_elements_by_tag_name("th") keys = [] for th in ths: keys.append(th.text) tds = self.chrome.find_elements_by_tag_name("td") vals = [] for td in tds: if "\n" in td.text: vals.append(td.text.replace("\n", "、")) else: vals.append(td.text) profile = {} for i in range(len(keys)): profile[keys[i]] = vals[i] return profile, keys, vals
⚓ 3-3. CSVエクスポート
TextExtractor#export_csv
はCSVファイルをエクスポートするためのキー、値、ファイルパスを引数に取る。
DataFrame
メソッドで空のデータフレームを生成する(pandas
のインポートをあらかじめしておくこと)。keys
とvals
をdf[ラベル]
に代入する。to_csv
メソッドにファイルパスを渡し、CSVファイルをエクスポートする。
def export_csv(self, keys, vals, path): df = pd.DataFrame() df["項目"] = keys df["値"] = vals df.to_csv(path)
⚓ 4. ユニットテスト
TestTextExtractor#setUp
はGoogle Chromeを起動し、ログイン - Webスクレイピング入門ページで指定されたユーザー名、パスワードでログインする。TestTextExtractor#test_get_lecturer_info
はTextExtractor#get_lecturer_info
が講師情報 - Webスクレイピング入門ページから取得した情報で生成したディクショナリーが適切なキー、値を含んでいるかを検証する。TestTextExtractor#test_export_csv
はTextExtractor#export_csv
がCSVファイルを指定したパスにエクスポートしているか検証する。
import unittest import sys sys.path.append("../lib") import os.path from os import path from text_extractor import TextExtractor class TestTextExtractor(unittest.TestCase): def setUp(self): self.text_extractor = TextExtractor("https://scraping-for-beginner.herokuapp.com/login_page") self.text_extractor.login("imanishi", "kohei") def test_get_lecturer_info(self): profile, *_ = self.text_extractor.get_lecturer_info() self.assertEqual({ "講師名": "今西 航平", "所属企業": "株式会社キカガク", "生年月日": "1994年7月15日", "出身": "千葉県", "趣味": "バスケットボール、読書、ガジェット集め" }, profile) def test_export_csv(self): _, keys, vals = self.text_extractor.get_lecturer_info() self.text_extractor.export_csv(keys, vals, "../csv/lecturer_info.csv") self.assertEqual(True, path.exists("../csv/lecturer_info.csv")) if __name__ == "__main__": unittest.main()