Pythonによるスクレイピングの方法について解説していきます
インターネットから欲しい情報を得るためには、
下記のような手作業が発生します
- webサイトにアクセス(url入力)
- キーワード入力したり(google検索エンジンなど)
- 何回かクリック操作(webサイト内を検索)
- 欲しい情報をファイルにまとめる
この記事を読むと上記の作業をPythonが実行してくれるようになりとても便利なります
まずはどのようなことができるかについて下の動画をご覧ください
▼動画の概要
- googleホームページにアクセス
- 検索キーワードに、「nobushige.com」入力 ~ Enter押下
- 検索結果の1位をクリック
(nobushige.com(nobby blog)が表示される) - PROGRAMMING(カテゴリ)クリック
(PROGRAMMINGの記事が表示される) - 各記事の情報(投稿日、タイトル、カテゴリ、アイキャッチ画像、url、スニペット)を取得
- csvファイルに保存
この記事では、nobushige.com(nobby blog)を例として説明しています
この操作はとても汎用性がひろく、ID&パスワードを入力してログインするタイプのwebサイト全般に使用できます
またwebサイト上の情報を一括で取得することもできるので、マーケティング関係など情報収集系の業務に使用できます
Jupyter Lab起動
Jupyter Labがインストールされていない方は下記の記事にインストール方法の説明がありますので参考にしてください
該当箇所は、目次からとどって、「2. エディタ入手」 >> 「2. Jupyter Lab(ジュピターラボ)入手」 にあります
Jupyter Labを起動させます
を記述してEnter押下
これでJupyter Labが起動します
ここではファイル名をわかりやすく「selenium.ipynb」としています
コードの説明
この記事で取り扱うPythonのコードについて説明してきます
ライブラリのインポート
from selenium.webdriver.common.keys import Keys
from webdriver_manager.chrome import ChromeDriverManager
import pandas as pd
from time import sleep
まだライブラリがインストールされていない場合は、下記の記事にライブラリのインストール方法の説明がありますので参考にしてください
該当箇所は、目次からたどって、「3.ライブラリ入手」にあります
ライブラリがインストールされているかどうかの確認はコマンドプロンプトから確認可能です
を記述してenter押下
インストールされているライブラリの一覧が表示されます
ライブラリの名前が表示されている場合はインストール済みです
seleniumからwebdriverをインポートしています
このwebdriverを仲介してブラウザを操作していきます
目的のwebサイトにアクセスしたりできるようになります
ブラウザ:Google Chrome, Internet Explore, Microsoft Edge などホームページを表示するもの
「Enter」などのキー操作ができるようになります
スクレイピングには、各ブラウザ用の「ドライバ」をダウンロードする必要があります
しかもブラウザが更新される度に、更新されたブラウザに適合したドライバをその都度ダウンロードする必要があります
これは結構面倒です(怒)
このような面倒な作業を自動で実行してくれるのがwebdriver_managerです
これをインポートしておくと自動的に現在のブラウザに適したドライバを自動でダウンロードしてくれます
これはとても便利です!!(おすすめです)
pandasをpdという名前でインポートします
毎回pandasと書くのが手間なので、代わりにpdと書いても使用できるようにしています
今回は複数のデータを取得します
記事の個数 ✕ 複数項目
このような複数のデータの塊をデータフレームという形でまとめてcsv形式で保存してくれるのがpandasとなります
time から sleepをインポートしています
webサイト上でクリック操作をして次のページに切り替わるまで若干時間がかかる場合があります
この切り替わり時間を見越して、待機時間を作ってくれるのが time の sleep となります
プログラミングは何も指定がしないと次々にコードを実行していきますので
意図的に待機時間を作って上げる必要があります
変数の設定
cols = [‘投稿日’,’タイトル’,’カテゴリ’,’URL’,’アイキャッチ’,’スニペット’]
df = pd.DataFrame(columns=cols)
b=webdriver.Chrome(ChromeDriverManager().install())
収集した情報をcsvファイルで保存します
収集した情報として、
‘投稿日’
‘タイトル’
‘カテゴリ’
‘URL’
‘アイキャッチ’
‘スニペット’
があります
保存先のファイルに先に名前をつけておきここに収集したデータを格納していきます
pandasのDataFrameメソッドで空のデータフレームを作っておきます
データフレーム:縦✕横にデータをまとめる2次元的な形式
A | B | C | |
a | 1 | 2 | 3 |
b | 4 | 5 | 6 |
c | 7 | 8 | 9 |
現在のブラウザのバージョンに適したドライバをインストールしてbに代入します
ChromeDriverManager(ドライバ自動インストール)がうまく動かない場合は
代わりに下記のコードをご使用ください
(社内ネットワークの設定の関係で、ChromeDriverManagerが使用できない場合があります)
●●●● の箇所は、ご使用のPCによって異なります
※ selenium v4.3.0から、webdriver.Chrome(executable_path=r”…\chromedriver.exe”) が使用できないことがあります(2022年6月24日から)
対処法①:以前のバージョン(selenium v4.2.0)を使用する
対処法②:新しい記述方法に書き換える
CHROMEDRIVER = r”…\chromedriver.exe”
chrome_service = fs.Service(executable_path=CHROMEDRIVER)
b = webdriver.Chrome(service=chrome_service)
‘C:\Users\●●●●\Documents\Python\public_package\chromedriver.exe’ の部分は、
chromdriverを保存している場所のフルネームとなります
●●●● の箇所は、ご使用のPCによって異なります
chromedriverの入手
chromedriverの入手方法です
手元のPCのブラウザ(Chrome)のバージョンに対応しているchromedriverが必要となります
そのため、先ずは手元のPCのブラウザのバージョンを確認します
手元のPCのブラウザのバージョンを確認
手元のPCのブラウザのバージョンを確認する手順です
- Google Chrome起動
- 「Google Chromeの設定」クリック
- 「ヘルプ」~「Google Chromeについて」クリック
バージョンの右側に数字(例 104.0.5112.102)が表示されています
これが手元ののPCのブラウザのバージョンとなります
chromedriverのダウンロード
chromedriverはこちらのサイトからダウンロードできます
https://chromedriver.chromium.org/downloads
ここで手元のPCのブラウザと同じものを選択します(例 104.0.5112.79)
「chromedriver win32.zip」をクリック(※ OSがWindowsの場合)
クリックスをするとダウンロードが始まります
zipファイルを開くと「chromedriver.exe」というファイルがあります
これがchromedriverです
わかりやすいところに保管しておきます
「nobushige.com(nobby blog)」にアクセス(google経由)
e = b.find_element_by_class_name(‘gLFyf’)
e.send_keys(“nobushige.com”)
e.send_keys(Keys.ENTER)
e = b.find_element_by_class_name(‘MjjYud’).find_element_by_tag_name(‘a’)
e.click()
sleep(1)
e=b.find_element_by_id(‘navi-in’).find_element_by_link_text(‘PROGRAMMING’)
e.click()
googleのサイトにアクセス
検索ボックスにキーワードを入力
検索ボックスにキーワードを入力します
e.send_keys(“nobushige.com”)
googleの検索ボックスにキーワードを入力します
そのためには、googleの検索ボックスの要素を特定する必要があり、デベロッパーツールを使っていきます
デベロッパーツール:Google Chromeに標準搭載されている開発者用の検証ツール
webサイトはhtml方式で記述されており、その記述内容を確認することができます
他にもいろんなことができますが、ここでは要素と特定するために使用します
デベロッパーツールでgoogleの検索ボックスの要素を特定していきます
「Ctr + Shift + I」で、デベロッパーツールが表示されます
「Select an element in this page to inspect it」をクリック (または「Ctr + Shift + C」クリック)
と表示された箇所の背景が水色になり強調されます
ここがgoogleの検索ボックスの要素となります
このようにして要素を見つけていきます
となっていたので、属性名=class、属性値=”gLFyf”で要素を特定します
bの要素の中で、属性名=class + 属性値=”gLFyf” の要素を e に代入しています
.find_element_by_class_name() は、class名で要素を取得するseleniumのメソッドです
※ selenium v4.3.0から、.find_element_by_ が廃止されています(2022年6月24日から)
これが原因で、.find_element_by_ が使用できないことがあります
対処法①:以前のバージョン(selenium v4.2.0)を使用する
対処法②:新しい記述方法に書き換える
変更点 .find_element_by_ → .find_element(By.)
例 .find_element_by_class_name(“文字列”) → .find_element(By.CLASS_NAME,”文字列”)
また、「By.」を使用可能とするため
「from selenium.webdriver.chrome.by import By」の追記が必要となります
.send_keysは、( )内の文字列を要素に送信するseleniumのメソッドです
.send_keys(Keys.ENTER)は、enterキーを押下するseleniumのメソッドです
これでgoogleのwebサイトにアクセスして
検索ボックスに「nobushige.com」を入力し
enterキーを押下するところまでできました
これで検索結果が表示されます
「nobby blog」をクリック
「nobby blog」と表示されているリンクの要素を取得していきます
「nobushige.com」の検索結果で検索1位のところに「nobby blog」があります
e.click()
上記同様に、
デベロッパーツールを表示(「Ctr + Shift + I」クリック)
「Select an element in this page to inspect it」をクリック (または「Ctr + Shift + C」クリック)
の背景が水色になり強調されます
これはテキストが表示されているだけですのでurlがあるaタグを探します
があります。これが取得したい要素
があり、その左にある▼をクリックしてみます
が折りたたまれて
が表示されます
状況を整理すると
があり
の中に
がある
が欲しい要素となります
.find_element_by_class_name(‘MjjYud’)
を使うことで、
を取得できます
更に
.find_element_by_tag_name(‘a’)
をつながることで
を取得することができます
.click() は要素を(左)クリックするseleniumのメソッドです
webサイトの画面が切り替わるまで少し待機時間があるので、
1秒待ちます
もしこの設定をしなかったらwebサイトの画面が切り替える前に次のコードが実行してしまい
エラーになってしまいます
そのためwebサイトの画面が切り替わるタイミングでは、sleepを使って待機時間を確保しましょう
これで「nobby blog」がクリックされ
「nobby blog」が表示されます
「PROGRAMMING」をクリック
次はカテゴリーの「PROGRAMMING」をクリックします
「PROGRAMMING」と表示されているリンクの要素を取得していきます
これを実行するためのコードは下記となります
e.click()
先ほどと同様にデベロッパーツールを表示して要素を見つけていきます
デベロッパーツールを表示(「Ctr + Shift + I」クリック)
「Select an element in this page to inspect it」をクリック (または「Ctr + Shift + C」クリック)
この状態で、PROGRAMMINGをクリックすると
の背景が水色になり強調されます
「PROGRAMMING」というテキストがある要素ではありますが他にもこのような要素はあるので
もう少し範囲を絞っていきます
属性名idは、ページ内で属性値が一つしか持つことができないというルールがあります
今回の場合に要素を特定するときは、属性名idを見つけて範囲を絞っていきます
先ほど見つけた要素の上の方を見ていくと、
があります。今回はこれを利用します
状況は、
の中に、
があり、これが今回取得したい要素となります
.find_element_by_id(‘navi-in’)
を使って、
を取得します
続けて、
.find_element_by_link_text(‘PROGRAMMING’)
をつなげることで、この中にある
を取得します
.find_element_by_link_text は、リンクテキストで要素を検索するseleniumのメソッドです
※ selenium v4.3.0から、.find_element_by_ が廃止されています(2022年6月24日から)
これが原因で、.find_element_by_ が使用できないことがあります
対処法①:以前のバージョン(selenium v4.2.0)を使用する
対処法②:新しい記述方法に書き換える
変更点 .find_element_by_ → .find_element(By.)
例 .find_element_by_link_text(“文字列”) → .find_element(By.LINK_TEXT,”文字列”)
また、「By.」を使用可能とするため
「from selenium.webdriver.chrome.by import By」の追記が必要となります
.click() で取得した要素を(左)クリックします
これで「nobby blog」の中のカテゴリー「PROGRAMMING」のページが表示されます
情報取得
下記のコードで記事の中から欲しい情報を取得していきます
ここでは
投稿日
タイトル
カテゴリ
アイキャッチ画像のURL
記事のURL
スニペット(概要)
を取得していきます
for e in es:
post_date = e.find_element_by_class_name(‘post-date’).text
title = e.get_attribute(‘title’)
category = e.find_element_by_class_name(‘cat-label’).text
url = e.get_attribute(‘href’)
eyecatch = e.find_element_by_tag_name(‘img’).get_attribute(‘src’)
snippet = e.find_element_by_class_name(‘entry-card-snippet’).text
s = pd.Series([post_date,title,category,url,eyecatch,snippet],index=df.columns)
df = df.append(s,ignore_index=True)
先ほどと同様にデベロッパーツールを表示して要素を見つけていきます
デベロッパーツールを表示(「Ctr + Shift + I」クリック)
「Select an element in this page to inspect it」をクリック (または「Ctr + Shift + C」クリック)
この状態で、投稿日をクリックすると
の背景が水色になり強調されます
これが欲しい要素ですが、記事は複数あるので記事毎に要素を確認するのは手間がかかります
そこで、各記事の中に投稿日やタイトルなどが同じように格納されているはずなので
先ずは各記事の要素(投稿日やタイトルなどが格納されている大きな要素)を取得していきます
先ほど見つけた要素の上の方を見ていくと
があります。これの左側の▼をクリックすると格納され
が複数並んでいます
これが各記事の要素(投稿日やタイトルなどが格納されている大きな用途)となります
更にその上を見ると
があります
状況を整理すると
といういう要素の中に複数の
という要素が格納されています
更に各要素の中に
投稿日やタイトルなどの要素が格納されています
先ほどまでは、
.find_element_by_tag_name()
を使って、検索で見つかった最初の要素を取得していました
今回は複数の要素を取得したいので
.find_elements_by_tag_name()
を使っていきます
※ element と elements 「s」があるかないかの違いです
先ず、
.find_element_by_id(‘list’)
で、
という要素を取得します
続けて、
.find_elements_by_tag_name(‘a’)
をつなげることで
この中に格納されている
という要素を全て取得します
複数の要素を取得しましたので
取得した複数の要素から一つずつ要素を取り出して
処理していきます
そのために下記のようなfor文を使っていきます
es の中にある要素を一つずつ取り出して、e に代入するという意味となります
取り出した一つずつの要素から
投稿日、タイトル、カテゴリ、url、アイキャッチのurl、スニペットを抽出していきます
title = e.get_attribute(‘title’)
category = e.find_element_by_class_name(‘cat-label’).text
url = e.get_attribute(‘href’)
eyecatch = e.find_element_by_tag_name(‘img’).get_attribute(‘src’)
snippet = e.find_element_by_class_name(‘entry-card-snippet’).text
投稿日は、
デベロッパーツールで投稿日をクリックすると
という要素に、投稿日があります
.find_element_by_class_name(‘post-date’)
を使って、要素を取得します
更に
.text
をつなげることで取得した要素内のテキスト情報を取得します
取得したテキスト情報をpost_dateに格納します
タイトルは、
同じ要素内の title=”” のところにあります
この場合は、取得した要素に
.get_attribute(‘title’)
をつなげることで
title=”” のところの情報を取得できます
取得した情報をtitleに格納します
カテゴリは、
デベロッパーツールでPROGRAMMINGをクリックすると
という要素が見つかります
.find_element_by_class_name(‘cat-label’)
を使って
という要素を取得し
.text
をつなげることで取得した要素内のテキスト情報を取得します
取得したテキスト情報をcategoryに格納します
urlは、
の中のhref=”” のところとなります
この場合は要素に
.get_attribute(‘href’)
をつなげることで取得できます
取得した情報をurlに格納します
アイキャッチ画像は、
の src=”…” のところにあります
先ず
.find_element_by_tag_name(‘img’)
を使って
という要素を取得し、続けて
.get_attribute(‘src’)
をつなげることで
src=”…”のところを取得します
取得した情報をeyecatchに格納します
スニペットは、
という要素にあります
.find_element_by_class_name(‘entry-card-snippet’)
を使って
という要素を取得します、更に
.text
をつなげることでこの中にあるテキスト情報を取得します
取得したテキスト情報をsnippetに格納します
各変数(post_date, title, category, url, eyecatch, snippet)に格納したバラバラの情報を
配列として一つに格納します
.Series
を使うことで複数の情報を配列で格納できます
[ ](角かっこ)の中に複数の情報を代入し、「,」(カンマ)で区切ります
index=df.columns
を記述することで見出しは、df.columnsと同じものを使うことができます
複数の情報を格納した配列を s に格納します
複数の情報を配列で格納したら
今度は配列自身も複数あるので
複数の配列を一つのデータフレームに格納します
.append
を使うことでデータフレームに配列を追加していくことができます
( )内に、s を記述することで s という配列を追加しています
ignore_index=True
を記述することで縦方向の見出しは省略されます
※ 配列をデータフレームに追加するときは縦方向の見出しは不要ですのでこのように記述します
csvファイルとして保存
これで各記事の中にある情報(投稿日やタイトルなど)を
一つのデータフレームに格納できました
次はこのデータフレームの情報をcsv形式で保存します
●●●● の箇所は、ご使用のPCによって異なります
.to_csv
を使うことでデータフレームの情報をcsv形式で保存します
( )内には、保存先とファイル名を記述します
保存先を省略する場合は、ipynbファイルと同じ場所に保存されます
encoding=’utf-8-sig’
を記述することで日本語フォントの文字化けを防止ます
※ これをしていないと日本語フォントは文字化けしていしまいます
pandasでデータフレームをcsv形式で保存する場合はencoding=’utf-8-sig’をします
コードの起動
Jupyter Lab に記述したコードを起動させます
Jupyter Labの画面で
Run the selected cells and advenceをクリック(または、「Shift + Enter」)
これでコードが起動します
この記事で使用した.ipynbファイルはこちらからどうぞ
今回は Python のselenium を使ってスクレイピングの方法について解説しました
題材として「nobby blog」を使用しました
webサイトにアクセス ~ ID/パスワード入力 ~ クリック という作業はよくある作業です
これを自動化するととても便利です
私も「webサイトにアクセス ~ ID/パスワード入力 ~ クリック」でログインするwebサイトは
ほとんどPythonで自動化しています
とても便利でもう元には戻れないと思います
この便利さを皆様にも体験していただけると幸いです
コメント