## はじめに
「PythonによるWebスクレイピング」を読んで、Seleniumを使って、ログインフォームのあるサイトにログインして、情報を取得してみたいと思い、個人的な要望から、SBI証券にログインして、口座の残高情報を取得してみました。初学者が見よう見まねで、書いたので、そのへんはご理解いただけますと幸いです。
Seleniumとは
Seleniumとはブラウザの操作を自動化するツールで、WebアプリのUIのテストや今回のようにスクレイピングに使用するツールです。今回はヘッドレスブラウザ(コマンドラインなどで使用するブラウザ)と組み合わせて使用しています。
実行環境
mac OSX
Python 2.7.1
## 苦労したところ
- まだ、初心者なので、サイトの要素を探すところで苦労しました
- あと、リスト型の取扱。途中でめんどくさいかったので、Pandasのデータフレーム型を使用してます。二次元配列からうまくCSVに出力する方法がわからなかったので。
- レンダリングは単純に10秒待つだけなので、その辺を改善したいと思っています。
ソース
このプログラムを実行して何かあっても責任を取れませんので自己責任でお願いします。
#coding:UTF-8
import pandas as pd
import csv
from selenium import webdriver
from bs4 import BeautifulSoup
##Selenumでログインし口座情報のページのHTMLを取得
def fetch_sbi_account_html(user_id,user_password):
driver = webdriver.PhantomJS()
print 'driver start'
driver.get('https://www.sbisec.co.jp/ETGate')
uid = driver.find_element_by_name('user_id')
password = driver.find_element_by_name('user_password')
uid.send_keys(user_id)
password.send_keys(user_password)
driver.find_element_by_name('ACT_login').click()
driver.implicitly_wait(10)
driver.find_element_by_link_text('口座管理').click()
driver.implicitly_wait(10)
driver.find_element_by_link_text('評価額').click()
driver.implicitly_wait(10)
#確認用にキャプチャも取得
driver.save_screenshot("sbi_account.png")
html = data = driver.page_source.encode('utf-8')
driver.quit()
print 'driver quit'
return html
#listを分割する。リストの成型に必要だったため。
def chunked(iterable, n):
return [iterable[x:x + n] for x in range(0, len(iterable), n)]
#HTMLをパースして、口座の情報を取得
def parse_table(tables,table_num):
arr = []
rows = tables[table_num].findAll("tr")
for j in range(2,len(rows)):
cells = rows[j].findAll(['td'])
for cell in cells:
text = cell.get_text()
if u"現買"not in text and u"買付" not in text:
arr.append(text)
arr = chunked(arr,5)
header = ["name","amount","price","value","total_amont"]
df = pd.DataFrame(arr, columns = header)
return df
if __name__ == '__main__':
#IDとパスワードのところは変更してください。
html = fetch_sbi_account_html('[your_id]','[your_password]')
bsObj = BeautifulSoup(html, "html.parser")
tables = bsObj.findAll("table" ,width="300")
#取得するテーブルの選択。この辺は適当です。CSVで出力します。
table_type = {"stock":3 ,"found":4, "found_nisa":5}
for key, v in table_type.items():
file_name = key + '.csv'
data = parse_table(tables,v)
data.to_csv(file_name, index=False, encoding='UTF-8',sep='\t')
print 'saved '+ file_name