株探より、日経平均やTOPIXなど指数の値を取得する例を通して、スクレイピングの始め方をまとめました!
取得のターゲットは、株探のこちらの赤枠の部分の値になります。

それでは行きましょう!
以下のステップで進めていきます。
- プロジェクトを作成する
- Spiderを作成する
- データの取得(スクレイピング)コードを記述
STEP1:プロジェクトを作成する
プロジェクトを作成するために、Pythonのscrapyでは、まずその前に、そのプロジェクトを実行するための環境を作る必要があります。
それでは仮想環境を作っていきましょう!
ANACONDAで仮想環境を構築する
ANACONDAを開く
するとこんな画面が表示されます。

ANACONDAが未インストールの場合は、こちらが参考になりますのでご参照ください。
サイドメニューから「Environments」を選択

ここで仮想環境を作ります。
ANACONDAを使うことで、仮想環境を構築することができ、それぞれ個別のライブラリをインストールすることができます。
デフォルトでは、「base(root)」という環境が1つだけ構築されています。

新しく仮想環境を作る

左下の「Create」をクリック

今回は、「scrapy_stock」という名前で作成します。
PackagesのPythonの欄にチェックが入っていることも確認すること!
すると、環境が作成されます。
この仮想環境はHome画面からも確認がきます。

ここに表示されているものが、この仮想環境でインストールされているライブラリです。
terminalを開く
作成した仮想環境の名前の右側にある矢印をクリックすると「Open Terminal」が出てくるので、クリックしてterminalを起動します。

pip install
terminalを開いたら、ここで必要なライブラリをpip installします。
インストールしたいライブラリをテキストファイルにまとめて、それを読み込ませて一括で実行します。
今回インストールするライブラリの一覧はこちら
ipython==7.22.0
pylint==2.7.2
autopep8==1.5.6
scrapy==2.4.1
scrapy-selenium==0.0.7
pymongo==3.11.3
pillow==8.2.0
dnspython==1.16.0
shub
このテキストファイルをお好みのディレクトリに保存し、terminalでそのディレクトリに移動します。
ここでは、workspaceディレクトリ下のscrapyディレクトリに保存するとします。
ANACONDAでterminalを開いた状態のデフォルトでは、ルートディレクトリとなっているので、ディレクトリをscrapyまで移動します。
% cd workspace
% cd scrapy
ここで、pip installを実行します。
% pip install -r requirements.txt
すると、インストールが走ります。
ANACOINDAに戻ります。
すると、scrapy等のライブラリがインストールされていることが確認できます。
これでやっと開発環境を構築できました。
ANACONDAの仮想環境にVScodeのpathを通す(macのみ必要)
Python実行時に、ちゃんと作成した仮想環境が実行されるよう、macの場合はpathを通す必要があります。
これまでの手順より、ANACONDAでターミナルを開き、以下コマンドを実行します。
% conda info -e
これにより仮想環境のパスを確認することができます。
VScodeを開き、設定します。

設定画面を開きます。
「Search settings」の欄に「python.defaultInterpreterPath」と入力し検索します。

ここに、先程ターミナルで確認した以下のようなパスを貼り付けます。
/Users/[username]/opt/anaconda3/envs/scrapy_stock
これで準備はOKです!VScodeとANACONDAの仮想環境の連携ができました。
プロジェクトの作成
それでは本題のプロジェクトの作成をしていきます。
ANACONDAよりterminalを開きます。開き方は前述したこちらの通り。
ここでプロジェクトフォルダを作成します。
私の場合、workspaceに移動し、そこに、「stock_scraping」というプロジェクトを作成します。
% cd workspace
% mkdir stock_scraping
% cd stock_scraping
ディレクトリを作成しましたので、この中に、scrapyのstartprojectコマンドを使ってプロジェクトを作ります。
ここでは、プロジェクト名を「stock_toscrape」としてプロジェクトを作ります。
% scrapy startproject stock_toscrape
これで、以下の階層でプロジェクトができました。
workspace > stock_scraping > stock_toscrape
作成したプロジェクトに移動します。
% cd stock_toscrape
Step2:Spiderを作成する
Spiderの作成
Spider名を「stocks_index」として作成します。
URLは、前のプロトコル(https://)部と最後の/は削除して貼り付けます。
ここでURLを指定することで、Spiderがアクセスできるドメインを設定しています。
% scrapy genspider stocks_index kabutan.jp
Created spider 'stocks_index' using template 'basic' in module:
stock_toscape.spiders.stocks_index
VScodeを立ち上げ、「stock_scraring」下の「stock_toscrape」フォルダを開きます。
Spiderの設定
Spiderの設定をします。
以下ファイルを開きます。
stock_scraring > stock_toscape > spiders > settings.py
このファイルの最後に行を追加して設定を記述します。
出力ファイルの文字コードを指定
指定することで文字化けしないようにします。
FEED_EXPORT_ENCODING = 'utf-8'
Download delayを設定
ページをダウンロードしてから、次のページをダンロードするまでの間隔を指定します。
これはサーバーに負荷をかけすぎないようにするためです。
28行目に予め記述があるのでコメントアウトを解除します。
これを0.3secに設定します。
DOWNLOAD_DELAY = 0.3
Step3:データの取得(スクレイピング)コードを記述
spiderがスクレイピングを開始するurlを記した”start_urls”を一部修正します。
- デフォルトではhttpで作成されるため、httpsに修正
- 末尾の/を削除
import scrapy
class StocksIndexSpider(scrapy.Spider):
name = 'stocks_index'
allowed_domains = ['kabutan.jp']
start_urls = ['https://kabutan.jp']
def parse(self, response):
pass
parseメソッド内を編集していきます。
scrapyの一連の流れはこうなっています!
- リクエストがstart_urlsのURLに送られる
- webサイトからのレスポンスをparseメソッドで受ける
この中にXpath等を記述することで情報の抽出ができる。
XPathを指定
指数の値の、XPathを記述します。
import scrapy
class StocksIndexSpider(scrapy.Spider):
name = 'stocks_index'
allowed_domains = ['kabutan.jp']
start_urls = ['https://kabutan.jp/']
def parse(self, response):
indexes = response.xpath('//div[@class="box1"][1]/table[@class="sub_shihyou"][1]/tr/td[@class="close"]')
XPathの書き方の詳細はこちらをご覧ください。
この記述で正常に値の取得ができているか、yieldを用いて確認をしていきます。
import scrapy
class StocksIndexSpider(scrapy.Spider):
name = 'stocks_index'
allowed_domains = ['kabutan.jp']
start_urls = ['https://kabutan.jp']
def parse(self, response):
indexes = response.xpath(
'//div[@class="box1"][1]/table[@class="sub_shihyou"][1]/tr/td[@class="close"]')
yield {
'indexes': indexes
}
spiderを実行します。
% scrapy crawl stocks_index
今回取得したかった値のpathはこちら
//div[@class="box1"][1]/table[@class="sub_shihyou"][1]/tbody/tr/td[@class="close"]
しかし、このpathの通りtbodyを付けるとどうも取得ができない。
Scrapyでtbodyは使えないようです!
そこでtbodyを無しにして、以下にすると、無事に取得することができました!
'//div[@class="box1"][1]/table[@class="sub_shihyou"][1]/tr/td[@class="close"]'
実行結果の中身を確認すると以下の結果が出力されており、正常に取得できていることがわかります。
2022-04-10 12:14:03 [scrapy.core.scraper] DEBUG: Scraped from <200 https://kabutan.jp>
{'indexes': [
<Selector xpath='//div[@class="box1"][1]/table[@class="sub_shihyou"][1]/tr/td[@class="close"]' data='<td class="close">26,985.80</td>'>,
<Selector xpath='//div[@class="box1"][1]/table[@class="sub_shihyou"][1]/tr/td[@class="close"]' data='<td class="close">1,896.79</td>'>,
<Selector xpath='//div[@class="box1"][1]/table[@class="sub_shihyou"][1]/tr/td[@class="close"]' data='<td class="close">17,098.66</td>'>,
<Selector xpath='//div[@class="box1"][1]/table[@class="sub_shihyou"][1]/tr/td[@class="close"]' data='<td class="close">792.86</td>'>,
<Selector xpath='//div[@class="box1"][1]/table[@class="sub_shihyou"][1]/tr/td[@class="close"]' data='<td class="close">1,830.39</td>'>,
<Selector xpath='//div[@class="box1"][1]/table[@class="sub_shihyou"][1]/tr/td[@class="close"]' data='<td class="close">2,102.05</td>'>,
<Selector xpath='//div[@class="box1"][1]/table[@class="sub_shihyou"][1]/tr/td[@class="close"]' data='<td class="close">3,258.12</td>'>,
<Selector xpath='//div[@class="box1"][1]/table[@class="sub_shihyou"][1]/tr/td[@class="close"]' data='<td class="close">1,972.17</td>'>
]}
上記の通り、8個の指標を取得することができました。これを、for分で展開し、1つずつ取り出します。
import scrapy
class StocksIndexSpider(scrapy.Spider):
name = 'stocks_index'
allowed_domains = ['kabutan.jp']
start_urls = ['https://kabutan.jp']
def parse(self, response):
indexes = response.xpath(
'//div[@class="box1"][1]/table[@class="sub_shihyou"][1]/tr/td[@class="close"]')
for index in indexes:
yield {
'index': index.xpath('.//text()').get()
}
このget()は、テキストで取得する場合に必要となってきます。
JSON形式で値を取得します。
% scrapy crawl stocks_index -o index_close.json
これにより、プロジェクト直下にindex_close.jsonファイルが作成され、取得した値が表示されます。
[
{"index": "26,985.80"},
{"index": "1,896.79"},
{"index": "17,098.66"},
{"index": "792.86"},
{"index": "1,830.39"},
{"index": "2,102.05"},
{"index": "3,258.12"},
{"index": "1,972.17"}
]
株探から指数の値を取得することができました!
いろいろ作ったので、階層がわけわからないことになっていると思うので、最後にまとめておくと、以下のようになっています。

ここまでお読みいただきありがとうございました。
コメント