シュンカの日記

基本的に書きたいことを書いていくスタイル。

python+selenium+PhantomJSでスクレイピングしたデータをMySQLに格納するまで

【スポンサーリンク】

python+selenium+PhantomJSでスクレイピングしたデータをMySQLに格納するまでの手順です。
RUNNETというマラソンのポータルサイトがあるんですが、そこから大会のエントリーリストを取得し、MySQLにデータを格納します。

ちなみにRUNNETからはいろんな大会が見れていいんですが、欲しくない情報もいっぱいあるので、自分の欲しい大会情報だけ抽出して管理できたらな~と思いやってみました。

環境など

OS:Raspbian
Python:3.6.3(pyenv)
スクレイピング対象のWebページ:RUNNET(https://runnet.jp/entry/runtes/user/pc/RaceSearchZZSDetailAction.do)

selenium+PhantomJSをインストール

まずは、seleniumをインストールします

pip install selenium

PhantomJSをインストールします

wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2
tar xvf phantomjs-2.1.1-linux-x86_64.tar.bz2
sudo cp phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/local/bin/ #PATHの通ったディレクトリにコピーする
sudo apt-get install -y libfontconfig1 fonts-migmix #スクリーンショットを撮るために必要

以下コマンドでバージョン名が確認できればインストールされています。

phantomjs -v

Webページ(RUNNET)からデータを取得する

Webページを開く

Webページ(RUNNET)を開いてみます。

###test.py###
from selenium import webdriver
driver = webdriver.PhantomJS()
driver.get("http://runnet.jp/entry/runtes/user/pc/RaceSearchZZSDetailAction.do")

スクリーンショットを取って処理内容を確認することができます。

###test.py###
driver.save_screenshot('test.png')

test.pngを開くと以下のようになっています。RUNNETの大会検索のページを開くことができています。
f:id:nukano0522:20180108160339p:plain

要素にアクセスし、検索条件を指定する

このままだと余計な大会も検索されてしまうので、検索条件を指定して結果を絞り込みたいです。
ここでは、”フルマラソン”を検索条件に指定して、フルマラソンの大会リストを取得してみます。
開発者ツール(F12)から、フルマラソンの要素を調べます。
f:id:nukano0522:20180108161557p:plain

「id="dummy_distance02"」とあるので、下記のようにidを指定してやると、要素にアクセスできます。

###test.py###
#フルマラソン
elem_distance = driver.find_element_by_id("dummy_distance02")
elem_distance.click()

先ほどと同様に、スクリーンショットを確認してみます。”フルマラソン”にチェックが付いています。
f:id:nukano0522:20180108162102p:plain

開発者ツールから検索ボタンの要素を調べ、検索ボタンをクリックします。

###test.py###
#検索ボタンをクリック
elem_search=driver.find_element_by_id("easy_search")
elem_search.click()

フルマラソンの大会リストを取得する

各大会のクラス名は、下記のように「class="item"」となっています。この中に、大会名、開催場所、開催日といった欲しい情報が入っています。
f:id:nukano0522:20180108172951p:plain

ですので、For文を利用して、各itemに対して大会の情報を取得していきます。

###test.py###
info=[] #各大会の情報を格納するためのリストを定義
for e in driver.find_elements_by_css_selector(".item"):
	try:
		info.append({
			'name':e.find_element_by_css_selector(".title_run").text, #大会名
			'date':e.find_element_by_css_selector(".date").text, #開催日
			'place':e.find_element_by_css_selector(".place").text, #開催場所
		})
	except:
		pass

取得したデータをMySQLに格納する

MySQLでテーブルを作成しておく

いったんMySQL環境から、テーブルを作成します。

create table test_entry_list(name varchar(256), date varchar(100), place varchar(100));

MySQL-pythonをインストール

pythonからMySQLを扱うために、”MySQL-python”というライブラリを使います。
インストールします。

pip install MySQL-python

pythonからMySQLに接続する

pythonに戻ります。
データベース名、ユーザー名、パスワードを設定し、MySQLに接続します。

###test.py###
import MySQLdb
#MySQLにデータ格納
conn = MySQLdb.connect(db='DB名', user='ユーザー名', passwd='パスワード', charset='utf8mb4')
c = conn.cursor()

テーブルにデータを格納する

先ほど作成したテーブル”test_entry_list”に、info内の大会情報を格納します。
For文を利用して、1大会ずつ順番にINSERTしていきます。

###test.py###
#1大会ずつテーブルに格納
for dict in info:
	c.execute('insert into test_entry_list values(%(name)s, %(date)s, %(place)s)', {
	'name':dict['name'], 
	'date':dict['date'], 
	'place':dict['place'],
	}
	)
conn.commit() #コミット
conn.close()

テーブルにデータが格納されているか、確認してみます。
f:id:nukano0522:20180108171201p:plain

うまくいってます。

参考書籍