#株探先物オプションのスクレイピング。取得した文字列をコピペしてTEXTにして、
#CSVに出力してMysqlにインサートするコード
#URLと日付と月限は手動で毎回入力する必要がある。
#以前はファイル作成まで手動で作業していた。
#WEBページを開き
#先物オプションの出来高データを取得して
#テキストファイルにする
#所定のフォルダにコピー、移動する
#個人用クラスメソッドを使う。
いままでWebdriverライブラリを使用していたが、空白部分が自動で削除されてしまった。
削除してほしくなかったので、BeautifulSoupライブラリを使用した。こちらのほうはクロムは起動しないし純粋にhtmlの文字を空白を含めて取得してくれた。
以下は今回作ったコードの一部。class cGetOption()
なおdef returnDriver(self,lurl)はwebdriverを使用したもので実際には採用しなかった。
株探の先物オプションのURLを取得して
そのページの文字列を取得。このとき、ある文字列Aと文字列Bの間の文字を取得(findFirstStrのところ)
そしてタプルで、文字列とファイル名文字列を出力する
https://github.com/maseda1030/yahoofinance_python.git
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
import MySQLdb import os import re import sys import time import datetime import glob#ファイル一覧 import shutil#move from selenium import webdriver import importlib#再読み込みのためのライブラリ import requests#スクレイピング from bs4 import BeautifulSoup#スクレイピング import methodMysql#個人用メソッド pyファイル ###START importlib.reload(methodMysql) ##以下は毎回手動で確認すること #株探の市況の先物オプション、市場が開いている当日のPM4:06分頃と、翌日の朝AM6:30以降に更新される。 #土日祝は更新されないが、前日が市場が開いていると更新される。 optionUrl='https://kabutan.jp/news/marketnews/?b=n202103010692'#都度修正、毎日 useDate='2021/3/1'#オプション取り込みの日付 #都度修正、毎日 useMonth=3#月限 12月の作業はたいてい翌月である1月 #都度修正、月 useTable='Table_StockOption'#テーブルは固定 # print('START') print('chrome起動') obj=methodMysql.cGetOption() #このURLは手動でコピペする #BeautifulSoup版 tupleArray=obj.getOptionDataByBeautifulSoup(optionUrl) #webdriver版 #tupleArray=obj.getOptionData(optionUrl) a,b=tupleArray print(a)#text print(b)#年月日時分 path='/Users/toshiromaseda/Documents/2020年株関連/kabu_python/' obj.outputText(path,tupleArray) #file名は、年月日時分.txtになって保存される。 #ファイルの存在チェックで拡張子をつけてチェックする if b.find('.txt')>=0: pass else: ifile=b+'.txt' ##-- checkFlag='nashi' files=glob.glob(path+'*.txt') for file in files: if ifile in file:#ファイル名を含んでいればTRUE print(file) checkFlag='ari' break else: #print(file) checkFlag='nashi' if checkFlag=='nashi': print('ファイルが存在しないか、ファイル名が間違っています') sys.exit() csvfile='c_'+ifile.split('.')[0]+'.csv' methodMysql.checkFile(ifile)#check 取り込み済みのファイルかどうかを調べる try: ofile=open(csvfile,'tw') except FileNotFoundError as e: # FileNotFoundErrorは例外クラス名 print("ファイルが見つかりません", e) #print("強制終了") sys._exit()#ファイルがなければ終了#tryのときは_exit()が良いらしい except Exception as e: # Exceptionは、それ以外の例外が発生した場合 print(e) try:#ファイルが存在しないときのエラー処理try with open(ifile,'tr') as fin: for iline in fin: #ilineに、”コール”、”出来高”の文字がある行は無視するようにする #countで探すか 1行目、2行目は不要なのでDBにインサートしないための処理 if iline.count('コール')>=1 or iline.count('出来高')>=1: continue#以下は実行されない if len(iline)==1:#1文字は改行コードだろうから何もしない continue try: ofile.write(methodMysql.outMojiMKIII(iline)+'\n')#MKIII改良版2020/12/18 #次はMysqlに直接インサートするバージョンを作業する except Exception: print("do not") ofile.close() except FileNotFoundError as e: # FileNotFoundErrorは例外クラス名 print("ファイルが見つかりません。パス、ファイル名を確認してください", e) ofile.close() print("強制終了") sys._exit()#ファイルがなければ終了 #tryのときは_exit()が良いらしい except Exception as e: # Exceptionは、それ以外の例外が発生した場合 print(e) #CSVからMysqlへ CSVファイルがないと実行できない。重複チェックなし #csvToMysql(difileはCSVファイル名,dtablename、doptionDate日付、dmonth月限) #テスト用テーブルTest_Table_StockOption print("csvtoMysql") methodMysql.csvToMysql(csvfile,useTable,useDate,useMonth) #Testが終わったら試す。 単独実行可能 但し、ファイルの移動先チェックがないので、他で移動がないことをチェックする必要あり methodMysql.fileMove(ifile,'./option_python_execute') methodMysql.fileMove(csvfile,'./option_python_execute') #表、グラフを出力する 単独実行可能 ##methodMysql.selectMysql('Table_StockOption') print("終わりました。") print('+++++++') print('chrome終了') print('END') ''' mysql> mysql> SELECT SUM(Volume1) as callVolume1, ExercisePrice, SUM(Volume2) as putVolume2 FROM Table_StockOption WHERE Month=3 GROUP BY ExercisePrice ORDER BY Exerce Desc; ''' |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
#先物オプションテキストコピペ 2021/02/28 class cGetOption(): def __init__(self): pass def returnDriver(self,lurl): # 仮想ブラウザ起動、URL先のサイトにアクセス driver = webdriver.Chrome('/usr/local/bin/chromedriver')#ここでエラーになったらパスが違うかchromedriverをインストールする #他のエラーで、「unexpectedly exited. Status code was:-9」だったら、Macの場合はシステム環境設定 → セキュリティとプライバシー で許可すればよい url=lurl driver.get(url) mydriver=driver return mydriver #BeautifulSoup版はクロムは起動しない def getOptionDataByBeautifulSoup(self,lurl):#BeautifulSoup対応版、別途Importが必要、2021/03/01 target_url = lurl r = requests.get(target_url) #requestsを使って、webから取得 soup = BeautifulSoup(r.text, 'lxml') #要素を抽出 shijyounews=soup.find(id="shijyounews")#id article=shijyounews.find("article")#tag tagTime=article.find("time")#tag mono=article.find(class_="mono")#class print("BeautifulSoup") #print(mono.text) outputFileName=tagTime.text#年月日時分 #ここに処理を入れる。 #2021/03/01 findFirstStr='コール プット'#を探して findSecondStr='株探ニュース'#の前までを取得する findFirstPosition=mono.text.find(findFirstStr) findSecondPosition=mono.text.find(findSecondStr) if(findFirstPosition>=0 and findSecondPosition>=0): print('search success.') outputText=mono.text[findFirstPosition:findSecondPosition] else: print('先物オプションが見つかりませんでした。URLが正しいか確認してください。') sys.exit() output=()#初期化 output=(outputText,outputFileName)#タプルで出力する,この時点で拡張子.txtは付記していない。 time.sleep(1) return output #webdriver版は、クロムが起動する。こっちは文字の先頭に空白を自動で削除する。この処理がよいときもあるが、今回は空白が必要だったのでB4にした def getOptionData(self,lurl): driver=self.returnDriver(lurl) time.sleep(1) #tag,id,css main = driver.find_element_by_id("wrapper_main") container=main.find_element_by_id("container") container_main=container.find_element_by_id("main") shijyounews=container_main.find_element_by_id("shijyounews") article=shijyounews.find_element_by_tag_name("article") tagTime=article.find_element_by_tag_name("time") mono=article.find_element_by_class_name("mono") #brs=mono.find_elements_by_tag_name("br") print(tagTime.text) outputFileName=tagTime.text#年月日時分 #tagTimePosition=tagTime.text.find('日') #print(tagTime.text[0:tagTimePosition+1])#年月日 #print(mono.text) findFirstStr='コール プット'#を探して findSecondStr='株探ニュース'#の前までを取得する findFirstPosition=mono.text.find(findFirstStr) findSecondPosition=mono.text.find(findSecondStr) if(findFirstPosition>=0 and findSecondPosition>=0): print('search success.') outputText=mono.text[findFirstPosition:findSecondPosition] else: print('先物オプションが見つかりませんでした。URLが正しいか確認してください。') sys.exit() output=()#初期化 output=(outputText,outputFileName)#タプルで出力する,この時点で拡張子.txtは付記していない。 time.sleep(1) driver.close()#起動したウィンドウを閉じる return output def outputText(self,path,tupleArray):#ここで受け取るタプルは2つ #getOptionData()からテキストとファイル名をタプルを受け取る outputText,filename = tupleArray if outputText=='' or filename=='' or path=='': print("パスかファイル名かテキストがありませんでした。filename,outputText") sys.exit() os.chdir(path)#ディレクトリ変更 print(os.getcwd())#ディレクトリ確認 if filename.find('.txt')>=0: pass else: filename+='.txt' try: ofile=open(filename,'tw') except FileNotFoundError as e: # FileNotFoundErrorは例外クラス名 print("ファイルが見つかりません", e) sys._exit()#ファイルがなければ終了#tryのときは_exit()が良いらしい except Exception as e: # Exceptionは、それ以外の例外が発生した場合 print(e) ofile.write(outputText) ofile.close() |