tsurutanのつぶやき

備忘録としてつぶやきます

Pythonでスクレイピングをしてみよう!

f:id:tsurutan:20161006123120j:plain

今回はPythonでスクレイピングをするやり方について説明しようと思います。

まだpythonを始めたばかりスクレイピングって難しそうだけどどうやってやるの?と苦しんでいる読者を想定しています。

Scrapingでできること

店舗一覧、商品一覧を抽出する ・ニュースサイトからヘッドライン一覧を抽出する ・ページのURLを全て抽出する などなど今まで煩わしかったことが解消できます!

Pythonの開発環境を整える

まずはPythonの開発環境を整えましょう。

ただ今回は日本語を今後扱うことを前提としてpython3のインストールの仕方について説明したいと思います。(pythonだと日本語の扱いがめんどくさい)

Homebrewのインストール

homebrewとはパッケージ管理システムで、ターミナルからコマンドを打ち込むことで簡単にインストールすることができます。

まずはxcodeツールが入っているか確認してください。

入っていなければ下記のコマンドを入力してください。

sudo xcode-select --install

そして次に公式サイトに書いてある通り

brew.sh

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

を入力してください。これで完成です。

python3のインストール

先ほどインストールしたbrewを使ってpython3を持ってきたいと思います。

まず

$ brew search python
app-engine-python                        python                                 
boost-python                             python3                                
gst-python                               wxpython                               
homebrew/versions/gst-python010          zpython                                
homebrew/apache/mod_python               Caskroom/cask/python                   
homebrew/python/python-dbus              Caskroom/cask/python3                  
homebrew/python/vpython                

と入力し、python3があることを確認しましょう。

確認が取れましたらpython3のインストールを行います。

brew install python3

はい、これで完成です。とても簡単ですね!

スクレイピングをしてみよう

スクレイピングをするにあたってまずseleniumBeautifulSoupをインストールしましょう。

これらをインストールするのもとても簡単で

pip3 install beautifulsoup4

pip3 install selenium

を入力すれば完了です。

また、seleniumではchrome driverというchromeを仮想的に立ち上げるドライバーが必要となるので

sites.google.com

ここからダウンロードし、適切なフォルダに保存しておいてください。(後でpathを指定するのでわかりやすいところに)

さて準備が整いましたのでコードに移っていきたいと思います。

news.yahoo.co.jp

今回はyahoo newsのトピック一覧から記事のタイトルと遷移先、カテゴリーを取ってくるところを実装してみたいと思います。

まず初めに先ほどインストールしたselniumとbeautifusoupをインポートします

from selenium import webdriver
from bs4 import BeautifulSoup

次にwebdriverの初期化を行います。

driver = webdriver.Chrome("/path/tmp/chromedriver")

webdriver.Chromeに渡しているのは先ほどダウンロードしたchrome driverのpathです。

そして本題、いよいよニュース記事の取得に入っていこうかと思います。

def get_yahoonews():
        driver.get("http://news.yahoo.co.jp/list/?c=world")
        html = driver.page_source
        soup = BeautifulSoup(html, "html.parser")
        for list in soup.body.find("ul", class_="list").find_all("li"):
            category = list.find("span", class_="cate").string
            title = list.find("span", class_="ttl").string
            href = list.a.get("href")

まずdriver.getの引数にyahoo newsの記事のurlを渡しております。 そして

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

webdriverで取得したhtmlを解析できるようにBeautifulSoupに渡します。

そして

for list in soup.body.find("ul", class_="list").find_all("li"):
            category = list.find("span", class_="cate").string
            title = list.find("span", class_="ttl").string
            href = list.a.get("href")

ここで解析を行ってタイトルと、カテゴリーと遷移先を取得しているのですが

まず一行目に

for list in soup.body.find("ul", class_="list").find_all("li")

と書いてあるのですがこれは、yahoo newsのページをhtmlで見てもられると分かるのですが(chromeであればCommand + Space + iで見ることができます)

f:id:tsurutan:20161006121605p:plain

このようにニュースがリスト状になっております。(liの中に記事が入っています)

よってこのニュースリストの要素をpythonで見れるようにfor分で回しているのです。

そして子要素を見てみると

f:id:tsurutan:20161006122139p:plain

このようにタイトルとカテゴリー、遷移先のurlが入っているので、これを

category = list.find("span", class_="cate").string
            title = list.find("span", class_="ttl").string
            href = list.a.get("href")

と書いて取得しているのです。

どうですか?簡単でしょう?

課題

アマゾンの食品一覧から、タイトル、遷移先を取得しなさい。

Amazon.co.jp: 食品: 食品・飲料・お酒

所感

www.tsurutan.com

以前Rubyでスクレイピングをする記事を書いたのですが、個人的にpythonの方が書きやすかった印象があります。

またChromeを仮想的に立ち上げることでiframeなどの時間差で表示されるものも取得できるのでとても使いやすかったです。

また、気をつけて欲しいのはスクレイピングを間を空けずやってしまうとDoS攻撃になってしまうので、10秒ほどの間隔を取ってやることにしましょう!

PythonによるWebスクレイピング

PythonによるWebスクレイピング

実践 Webスクレイピング&クローリング-オープンデータ時代の収集・整形テクニック

実践 Webスクレイピング&クローリング-オープンデータ時代の収集・整形テクニック

JS+Node.jsによるWebクローラー/ネットエージェント開発テクニック

JS+Node.jsによるWebクローラー/ネットエージェント開発テクニック