case-kの備忘録

日々の備忘録です。データ分析とか基盤系に興味あります。

Selenium+Chrome Driverで日経平均株価をスクレイピング

株価のアプリを作ろうかと考えてます。日経株価をBeautiful Soupでスクレイピングしようと思ったのですが、日経平均株価のサイトは年月日を指定することで数値が可変するサイトでしたのでSerenimでスクレイピングしました。Serenimはブラウザの操作が可能なのでJavaScriptを実行後のサイト情報の取得が可能です。

code

github.com

Selenium WebDriver

日経株価サイト
f:id:casekblog:20190927040410p:plain
SerenimでスクレイピングするためにSelenium Web Driverが必要です。Web Driverについてはこの記事がわかりやすかったです。
qiita.com
SeleniumのWeb Driverはいくつかあります。過去の書籍だとPhantomJSDriverが有名でしたがサポートが終了してしまったので、Chrome Driverを使ってスクレイピングしました。

# SeleniumのWeb Driver
ChromeDriver, EventFiringWebDriver, FirefoxDriver, HtmlUnitDriver, InternetExplorerDriver, PhantomJSDriver, RemoteWebDriver, SafariDriver
chrome Driber

www.seleniumhq.org

env

必要な環境を整えます。GCEのDebain環境で作りました。

wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo apt install ./google-chrome-stable_current_amd64.deb
google-chrome --version
> #Google Chrome 77.0.3865.90 

curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
sudo python get-pip.py
# Google Chromeに合わせてバージョンを指定:バージョンを指定しないと下記ののエラーが出ます。
# SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 78
sudo pip install chromedriver-binary==77.0.3865.40.0
sudo pip install selenium 
sudo pip install pandas

scraping_stock_price using headless option

Serenimを使ったスクレイピングでブラウザが立ち上がるのは嫌なので、ヘッドレスでブラウザが立ち上がらないように取得しました。

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.select import Select
import chromedriver_binary
import pandas as pd
import numpy as np
from time import sleep
import datetime

def scraping_stock_price(year,month):
    url = "https://indexes.nikkei.co.jp/nkave/archives/data"
    # Headless mode 
    options = webdriver.ChromeOptions()
    options.add_argument('--headless')
    driver = webdriver.Chrome(options=options)  # 今は chrome_options= ではなく options=
    driver.get(url)
    
    # Change the drop down
    drop_dwon_year = driver.find_element_by_xpath('/html/body/div[4]/div/div[2]/div[1]/div[1]/select')
    Select(drop_dwon_year).select_by_visible_text('{}年'.format(year))
    drop_dwon_month = driver.find_element_by_xpath('/html/body/div[4]/div/div[2]/div[1]/div[2]/select')
    Select(drop_dwon_month).select_by_visible_text('{}月'.format(month))
    
    # Click display button
    driver.find_element_by_class_name("disp-button").click()
    sleep(3)
    stock_list, start_point , end_point = [], 11 ,20
    for idx, value in pd.DataFrame(driver.find_element_by_css_selector("#data_list > table") .text.encode('utf-8').split('\n'))[1:].iterrows():
        year = value.str[0:4][0]
        month = value.str[5:7][0]
        day = value.str[8:10][0]
        date = datetime.datetime.strptime(year+ "-"+month+"-"+day, '%Y-%m-%d')
        unixtime_jst = datetime.date(
            date.year,
            date.month, 
            date.day
        ).strftime('%s')
        open_price = value.str[start_point:start_point+9].str.replace(",", "")[0]
        high_price = value.str[start_point +10:end_point+10].str.replace(",", "")[0]
        low_price = value.str[start_point +20:end_point +20].str.replace(",", "")[0]
        end_price = value.str[start_point +30:end_point +30].str.replace(",", "")[0]
        stock_list.append([year,month,day,date,unixtime_jst,open_price , high_price,  low_price,end_price])
    stock_df = pd.DataFrame(stock_list,columns=['year','month','day','date','unixtime_jst','opening_price','high_price', 'low_price','end_price'])
    stock_df[['opening_price','high_price','low_price','end_price']] = stock_df[['opening_price','high_price','low_price','end_price']].astype(float)
    #stock_df.to_csv('./data/price_{}_{}.csv'.format(year,month))
    return  stock_df
# 2019年6月を取得        
stock_df = scraping_stock_price(2019,6)
stock_df .head()
   year month day       date unixtime_jst  opening_price  high_price  low_price  end_price
0  2019    06  03 2019-06-03   1559520000       20327.87    20438.03   20305.74   20410.88
1  2019    06  04 2019-06-04   1559606400       20435.86    20464.57   20289.64   20408.54
2  2019    06  05 2019-06-05   1559692800       20667.89    20800.64   20646.15   20776.10
3  2019    06  06 2019-06-06   1559779200       20745.84    20842.28   20745.84   20774.04
4  2019    06  07 2019-06-07   1559865600       20859.78    20907.77   20816.58   20884.71

日経平均株価の取得ができました。日経はリアルタイムデータもあるので、Pub/Subも使いGCPメインでアプリML系のアプリを作りたいと思います。


参考
computingforgeeks.com
watlab-blog.com
qiita.com