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