読者です 読者をやめる 読者になる 読者になる

高みを目指すブログ

都内近郊に住む暇を持て余した理系大学生が日常を綴るブログです。主なトピックは、勉強系では金融工学、人工知能、プログラミング、python、日常系では、色々なことを書いて行こうと思います。

pythonでYahoo!ファイナンスのニュース記事をスクレイピングする(1)

python 経済 ビッグデータ テキストマイニング

はじめに

近年、機械学習ビッグデータ人工知能分野の実務への応用が急速に増してきており、webの数値データを利用したりテキストを分析することでマーケティングに生かそうとすることが当たり前のように行われるようになった。また研究に於いても、web上の記録やデータから人間行動を解き明かそうとする研究が盛んに行われている。そうした中で必須となっているのが、web上のデータをプログラミングで抽出する「クローリング」や「スクレイピング」と言った技術である。

今回の記事では、スクレイピングの最も基本的な部分を実際のpythonコードを示すとともに紹介する。

何故pythonなのか

スクレイピングに関する本は多く出版されていると思うが、その多くはpython言語で記述されている。何故スクレイピングと言えばpythonなのか?これは1つに強力なサードパーティーライブラリの存在が大きいと思う。具体的にはrequests、Beautiful Soup等のライブラリを駆使するだけで、簡単にスクレイピングが可能になる。そして収集したデータをそのままpandasを使って整形しcsvに出力できることもできる。まぁとにかくpythonでやると大変楽ができるのである。スクレイピングの主な流れは以下のようである。

  1. google chromeの検証機能を使って取りたいデータの在りかを特定する
  2. requestsを使ってhtmlのテキストを取得する
  3. Beautiful Soupを使ってhtmlを解析する
  4. 必要な情報のみを切り抜く

google chromeの検証機能を使って取りたいデータの在りかを特定する

まず、スクレイピングしたいソースを確認する。今回は以下のニュース記事の本文のテキストをスクレイピングすることを目標とする。 f:id:aifinance:20170213233627p:plain スクレイピングしたい部分をドラッグして選択し、右クリックから検証を押すと次のようにhtml内のどの部分に本文があるかが特定できる。 f:id:aifinance:20170213234207p:plain 今回はclass=“ymuiContainerNopad clearFix s170"のdivの中に本文があることがわかる。

requestsを使ってhtmlのテキストを取得する

目的のテキストの在りかがわかったところで、次にrequestsを使ってhtmlのテキストをとってくる。

url = 'http://news.finance.yahoo.co.jp/detail/20170213-00000381-jijf-bus_all' # スクレイピングしたいサイトのURL
res = requests.get(url) # requestsのgetメソッドを使ってレスポンスを得る
html = res.text # 得られたレスポンスをtextに変換する

これで、htmlのテキストをとってくることができた。

Beautiful Soupを使ってhtmlを解析する

次にBeautiful Soupを使うがこれは以下の1行で済む(超簡単!)。

soup = BeautifulSoup(html, "html.parser")

必要な情報のみを切り抜く

最後に必要な部分のみの情報を切り抜いたらお仕舞いだが、実はここが一番面倒臭いときもある。

text_div = soup.find('div', {'class': 'ymuiContainerNopad clearFix s170'}) # 目的のテキストのあるブロックを切り抜く
text_div.get_text() # テキストのみを抽出
text = text_div.get_text().replace('\n', '') # \nを取り除く
text = text.replace('\u3000', '') # \u3000を取り除く

まとめ

以上のコードをまとめると以下のようになる。

import requests
from bs4 import BeautifulSoup

url = 'http://news.finance.yahoo.co.jp/detail/20170213-00000381-jijf-bus_all' 
res = requests.get(url) 
html = res.text [f:id:aifinance:20170214162021p:plain]
soup = BeautifulSoup(html, "html.parser")
text_div = soup.find('div', {'class': 'ymuiContainerNopad clearFix s170'})
text_div.get_text()
text = text_div.get_text().replace('\n', '')
text = text.replace('\u3000', '')

print(text)

結果は以下の通り。 f:id:aifinance:20170214162021p:plain 確かに、目的のテキストを文字データとして抽出することができた。 ここから色々遊ぶためにはMeCabにぶち込んで形態素解析したり、文字データを特徴ベクトル化したりなどの前処理が必要だがそういった込み入った話はまた次回以降に繰り越すことにする。