akatak’s blog

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

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

先日の日経新聞のマーケット欄に出ていました東証株式市場の空売り比率。これも今後の株式市場を占うのに大事な指標かと思いますので、Pythonを利用して、東証のホームページからWebスクレイピングしてみましょう。

東証 空売り比率」で、ググってみると、すぐに見つかりました。

https://www.jpx.co.jp/markets/statistics-equities/short-selling/index.html

ホームページを見ると、日付毎にPDFが張り付いているので、これらを一旦、作業ファイルに保存しておくことにしようと思います。そして、後でPDFからテキストデータを取り出せばいいと思いつつも、PDFからテキストデータをうまく取り出せるかな、とちょっと心配。

取り敢えず、まずは、いつものようにrequestsモジュールとBeautifulSoupモジュールを使ってスクレイピングを行っていきます。

import requests
from bs4 import BeautifulSoup

# urlとして、先ほど検索した東証「空売り集計」のトップページを指定。
url = 'https://www.jpx.co.jp/markets/statistics-equities/short-selling/'

res = requests.get(url)

# 東証HPだとデフォルトではres.encoding = 'ISO-8859-1'となり、res.textの漢字が文字化けしてしまう。
# そこで、以下の行を加えると、res.encoding = 'utf-8'となり、文字化けしなくなる。
res.encoding = res.apparent_encoding

# BeautifulSoupオブジェクトを生成。解析を行うパーサーとして'html.parser'を指定。
soup = BeautifulSoup(res.text, 'html.parser')

さて、ここで、Google Chromeの検証機能を使って、PDFファイルが格納されているディレクトリのリンクを特定しましょう。

以下の画像の通り、<div>タグのうち、<class="component-normal-table">となっているタグをまず指定し、その後、find_all()メソッドを使い、<a>タグを全て取得します。そして、get()メソッドの引数を"href"とすることで、リンクを取得します。

f:id:akatak:20180714195113p:plain

ただし、ホームページをよく見ると「空売り集計」欄だけでなく、「業種別集計」欄もあります。検証機能でリンクのPDFファイル名をよく見ると、「空売り集計」欄のファイル名の末尾は***-m.pdfとなっており、「業種別集計」欄の末尾は***-g.pdfとなっています。

今回は「空売り集計」欄のPDFだけ取得したいので、リンクの後から5文字目が"m"となっているリンクのみ取得するようにします。

# <class="component-noramal-table>となっている<div>タグで囲まれた範囲の情報を取得
s = soup.find('div', {'class': 'component-normal-table'})

# その範囲で、更に<a>タグで囲まれた情報を全て取得
a_tags = s.find_all('a')

pdf_list = []

# それらの<a>タグで囲まれた情報を一つ一つ取り出す。
for a_tag in a_tags:
    # get('href')メソッドで、hrefで指定しているリンクを取り出し、後ろから5文字目が"m"のリンクのみ取得して、pdf_listに追加する。
    if a_tag.get('href')[-5] == 'm':
        pdf_list.append(a_tag.get('href'))

これで、無事、リンクを取得できました。

['/markets/statistics-equities/short-selling/nlsgeu0000037ver-att/180713-m.pdf',
 '/markets/statistics-equities/short-selling/nlsgeu0000037t4d-att/180712-m.pdf',
 '/markets/statistics-equities/short-selling/nlsgeu0000037pl7-att/180711-m.pdf',
 '/markets/statistics-equities/short-selling/nlsgeu0000037nj9-att/180710-m.pdf',
 '/markets/statistics-equities/short-selling/nlsgeu0000037jr9-att/180709-m.pdf',
 '/markets/statistics-equities/short-selling/nlsgeu0000037h3w-att/180706-m.pdf',
 '/markets/statistics-equities/short-selling/nlsgeu0000037efl-att/180705-m.pdf',
 '/markets/statistics-equities/short-selling/nlsgeu00000379yi-att/180704-m.pdf',
 '/markets/statistics-equities/short-selling/nlsgeu000003764s-att/180703-m.pdf',
 '/markets/statistics-equities/short-selling/nlsgeu0000037115-att/180702-m.pdf']

このリンクは、東証トップページからの相対位置を示していますので、絶対位置に変換して、作業フォルダの下にtempフォルダを作り、そこに保存します。

import os
import urllib.request
import time

base_url = 'https://www.jpx.co.jp'

for i, x in enumerate(pdf_list):
    url = base_url + x
    urllib.request.urlretrieve(url,'temp/shortselling'+ str(i) + '.pdf')
    time.sleep(1)  # 礼儀として1秒待つ

ここまで、お疲れ様でした。さて、いよいよ次は、これらのPDFファイルから、必要なテキストを取得して、データ系列を作成し、可視化していきましょう。ただし、PDFファイルを取り扱うモジュールも必要になり、長くなってしまうので、次回にしたいと思います。それでは。