akatak’s blog

プログラム初心者の50代ビジネスマンがセカンドキャリアを目指して働きながらPythonを中心に独学しています。自らの覚え書きや感じたことなどを脈絡もなく書き連ねるブログです。

個人投資家のためのWebスクレイピング(4)〜 Pythonを使って、東証「空売り比率」を取得し、グラフ化してみよう【中】

さて、前回に続いて、東証空売り比率」のデータを取得して、グラフ化してみましょう。

前回、東証ホームページからPDFファイルを取得しましたので、次にそれらPDFファイルからテキストを抽出してみます。

PDFファイルからのテキスト取得については、以下のサイトで多少お世話になったPyPDF2を使ってみました。
Automate the Boring Stuff with Python

本サイトの元の英語本は、日本語に翻訳されています(こちら↓)。

ここに記載の通り、以下の通り試してみました。

import PyPDF2
# Open a PDF file.
fp = open('temp/shortselling0.pdf', 'rb')
pdfReader = PyPDF2.PdfFileReader(fp)
pageObj = pdfReader.getPage(0)
pageObj.extractText()

ですが、表示されたのは、文字化け。

'\'5Gˆ0£˚˜\n>Þ>Ü>Ý>ä>Û>ã>Û>Ý>ß\n0ɢd\nFÇ\n2ˇ5 \n>Ô>Õ\n˚ı"á\n>Ô>Õ>Û>Ô>Õ\n2ˇ5 \n>Ô>Õ\n˚ı"á\n>Ô>Õ>Û>Ô>Õ\n2ˇ5 \n>Ô>Õ\n˚ı"á\n>Ô>Õ>Û>Ô>Õ\n>Þ>Ü>Ý>ä>ã˙v>Ý>߈¥>Ý>Ø>ä>Ü>Ý>Ø>Þ>Ý>Þ>â>Ü>Ú>Þ>Ñ>å>ä>Þ>Ø>Ý>à>â>ß>Þ>Ú>ä>Ñ>Þ>Ü>â>Ø>â>â>Þ>â>Ú>å>Ñ>Þ>Ø>å>å>Ü>Ø>Ü>Þ>Ü\nFÿ˝4\'¼G"0£ˆX˛+\'ìF÷FÒG˙F¹\nGˆFþFûFÿ#ÝG"F¹\n˙vˆ¥\n˜@ˆe\'5Gˆ˝A0dFÒGˆ\'5Gˆ˝A0dFúFç\n0£\n>Ô>Õ\n'

こちら↓によると、PyPDF2のextractTextは貧弱な機能のようです。こちらに記載のようにpdfminer(python3系ではpdfminer3k)を使ってみることにしました。

teratail.com

pdfminer3kに関しては、こちらのブログ記事のスクリプトをほぼそのまま使わせていただきました。

cartman0.hatenablog.com

from pdfminer.pdfparser import PDFParser
from pdfminer.pdfparser import PDFDocument
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.pdfparser import PDFPage
from pdfminer.pdfdevice import PDFDevice
from pdfminer.converter import PDFPageAggregator
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from pdfminer.layout import LTTextBoxHorizontal

# Open a PDF file.
fp = open('temp/shortselling0.pdf', 'rb')

# Create a PDF parser object associated with the file object.
parser = PDFParser(fp)
document = PDFDocument()
parser.set_document(document)

# Create a PDF document object that stores the document structure.
# Supply the password for initialization.
password=""
document.set_parser(parser)
document.initialize(password)

# Create a PDF resource manager object that stores shared resources.
rsrcmgr = PDFResourceManager()

# Set parameters for analysis.
laparams = LAParams()

# Create a PDF page aggregator object.
device = PDFPageAggregator(rsrcmgr, laparams=laparams)
interpreter = PDFPageInterpreter(rsrcmgr, device)

pages = list(document.get_pages())
page_1 = pages[0] # 1st page
page_1

# interpreter page1
interpreter.process_page(page_1)

# receive the LTPage object for the page.
# layoutの中にページを構成する要素(LTTextBoxHorizontalなど)が入っている
layout = device.get_result()
# print(layout)

text = []

for l in layout:
#     print(l) # l is object
    if isinstance(l, LTTextBoxHorizontal):
        text.append(l.get_text())

print(text)

これを実行してみると、以下の通り、きれいに出力されました。

['空売り集計(日次)\n',
 '年月日\n',
 '実注文\n',
 '空売り(価格規制あり)\n',
 '空売り(価格規制なし)\n',
 '売買代金\n(a)\n',
 '比率\n(a)/(d)\n',
 '売買代金\n(b)\n',
 '比率\n(b)/(d)\n',
 '売買代金\n(c)\n',
 '比率\n(c)/(d)\n',
 '2018/7/13\n(株)東京証券取引所\n',
 '【単位:百万円】\n',
 '合計\n(d)\n',
 '2018年7月13日\n',
 '1,801,212\n',
 '60.2%\n',
 '982,146\n',
 '32.8%\n',
 '206,662\n',
 '6.9%\n',
 '2,990,020\n',
 '(注1)数値は外国株券等を含む合計数値(概算)である。\n(注2)空売りの中には信用取引を含む。\n']

上記のテキストデータから、12番目(日付)と17番目(実取引の割合)を抽出して加工すれば、必要なデータが得られます。 日付については、"\n"でsplit。その最初のテキストを更に"/"でsplit。それらをyear, month, dayに格納し、datetimeオブジェクトに変換します。

year, month, day = text[11].split('\n')[0].split('/')
datetime.datetime(int(year), int(month), int(day))

次に、空売り比率ですが、実取引の割合をテキストから小数に変換し、100から引けば算出できます。

100 - float(text[16].rstrip('%\n'))

これらを先ほどのスクリプトに加えて、取り込んだ複数のファイルを処理できるように forループにします。そこで得られたデータ系列をもとに、matplotlibで描画すれば出来上がり。

f:id:akatak:20180716090648p:plain

PDFファイルからテキストを取得するのに、多少苦労しましたが、何とかグラフ化までこぎ着けました。 参考までに最後にスクリプトを掲載しておきます。

今回のデータ系列は少しでしたが、バックデータは過去12ヶ月分あるようなので、それらも取り込めるように工夫することも必要かもしれません。

東京証券取引所「空売り比率」推移

akatak.hatenadiary.jp

akatak.hatenadiary.jp