書籍概要

Pythonクローリング&スクレイピング[増補改訂版]
―データ収集・解析のための実践開発ガイドー

著者
発売日
更新日

概要

Pythonによるクローリング・スクレイピングの入門から実践までを解説した書籍です。2017年の初版から内容をアップデート,新ライブラリの解説などを追加した増補改訂版です。基本的なクローリングやAPIを活用したデータ収集,HTMLやXMLの解析から,データ取得後の分析や機械学習などの処理まで解説。データの収集・解析,活用がしっかりと基本から学べます。Webサービスの開発やデータサイエンスや機械学習分野で実用したい人はもちろん,基礎から解説しているのでPython初心者でもつまずかずに学習できます。多数のライブラリ,強力なフレームワークを活用して高効率に開発できます。

こんな方におすすめ

  • 業務や学術研究でクローラーを作りたい人
  • Pythonの一歩先の活用方法に興味のある人

サンプル

samplesamplesamplesamplesample

目次

1. クローリング・スクレイピングとは何か

  • 1-1. 本書が取り扱う領域
  • 1-2. Wgetによるクローリング
  • 1-3. スクレイピングに役立つUnixコマンド
  • 1-4. gihyo.jpのスクレイピング
  • 1-5. まとめ

2. Pythonではじめるクローリング・スクレイピング

  • 2-1. Pythonを使うメリット
  • 2-2. Pythonのインストールと実行
  • 2-3. Pythonの基礎知識
  • 2-4. Webページを取得する
  • 2-5. Webページからデータを抜き出す
  • 2-6. データをファイルに保存する
  • 2-7. Pythonによるスクレイピングの流れ
  • 2-8. URLの基礎知識
  • 2-9. まとめ

3. ライブラリによる高度なクローリング・スクレイピング

  • 3-1. HTMLのスクレイピング
  • 3-2. XMLのスクレイピング
  • 3-3. データベースに保存する
  • 3-4. クローラーとURL
  • 3-5. Pythonによるクローラーの作成
  • 3-6. まとめ

4. 実用のためのメソッド

  • 4-1. クローラーの特性
  • 4-2. 収集したデータの利用に関する注意
  • 4-3. クロール先の負荷に関する注意
  • 4-4. 繰り返しの実行を前提とした設計
  • 4-5. まとめ

5. クローリング・スクレイピングの実践とデータの活用

  • 5-1. データセットの取得と活用
  • 5-2. APIによるデータの収集と活用
  • 5-3. 時系列データの収集と活用
  • 5-4. オープンデータの収集と活用
  • 5-5. Webページの自動操作
  • 5-6. JavaScriptを使ったページのスクレイピング
  • 5-7. 取得したデータの活用
  • 5-8. まとめ

6. フレームワーク Scrapy

  • 6-1. Scrapyの概要
  • 6-2. Spiderの作成と実行
  • 6-3. 実践的なクローリング
  • 6-4. 抜き出したデータの処理
  • 6-5. Scrapyの設定
  • 6-6. Scrapyの拡張
  • 6-7. クローリングによるデータの収集と活用
  • 6-8. 画像の収集と活用
  • 6-9. まとめ

7. クローラーの継続的な運用・管理

  • 7-1. クローラーをサーバーで実行する
  • 7-2. クローラーの定期的な実行
  • 7-3. クローリングとスクレイピングの分離
  • 7-4. クローリングの高速化・非同期化
  • 7-5. クラウドを活用する
  • 7-6. まとめ

Appendix. Vagrantによる開発環境の構築

  • A-1. VirtualBoxとVagrant
  • A-2. CPUの仮想化支援機能を有効にする
  • A-3. VirtualBoxのインストール
  • A-4. Vagrantのインストール
  • A-5. 仮想マシンを起動する
  • A-6. ゲストOSにSSH接続する
  • A-7. Pythonのスクリプトファイルを実行する
  • A-8. Linuxの基本操作
  • A-9. Vagrantで仮想マシンを操作するコマンド

サポート

ダウンロード

サンプルファイルのダウンロード

(2021年1月29日更新)

本書のサンプルファイルをご利用いただけます。

ダウンロード
サンプルファイル(sample_codes_2021-01-28.zip)

正誤表

本書の以下の部分に誤りがありました。ここに訂正するとともに,ご迷惑をおかけしたことを深くお詫び申し上げます。

(2021年10月4日最終更新)

P.102 リスト3.10の保存・実行に関する説明

このスクリプトを名前で保存して実行すると、
このスクリプトをsave_mongo.pyという名前で保存して実行すると、正しいソースコード

P.105 表3.2の強調部分

書籍中で本来強調される部分が強調されていませんでした。本来は下記箇所が強調されます。


https://stocks.finance.yahoo.co.jp/stocks/detail/?code=8411
https://www.amazon.co.jp/dp/B00QJDQM9U
https://twitter.com/TwitterJP/status/1017144330211880960
http://www.itmedia.co.jp/news/articles/1807/26/news115.html

(以下2020年6月4日更新)

P.79 Beautiful Soupの実行例でtitle要素を取得する例

>>> soup.h1 # soup.titleのようにタグ名の属性で、title要素を取得できる。
>>> soup.title # soup.titleのようにタグ名の属性で、title要素を取得できる。

(以下2019年10月21日更新)

P.71 2.7のsave(filepath: str, books: List[dict])の説明

CSVとすべき箇所がSQLiteとなっていました。

引数booksで与えられた書籍のリストをSQLiteデータベースに保存する。
引数booksで与えられた書籍のリストをCSV形式のファイルに保存する。

(以下2019年10月8日更新)

P.62 2.5のインタラクティブシェルの実行例

インタラクティブシェルの実行例のうち,下記の2行は誤りでした。これを実行するとNoneが帰ってくるため,実際には何も表示されません。


>>> h1.text  # text属性で要素のテキストを取得できる。
'今日のくだもの'

(以下2019年8月22日更新)

P.13 1.3の脚注10

サンプルファイルのダウンロードリンクが前版を示していました。なお,前版にも同等のファイルがあるため動作はします。

このファイルは書籍のサンプルファイル(https://gihyo.jp/book/2017/978-4-7741-8367-1)に含まれています。
このファイルは書籍のサンプルファイル(https://gihyo.jp/book/2019/978-4-297-10738-3)に含まれています。

P.199 5.4.2の新幹線旅客輸送量の推移のURL

httpsとすべきURLをhttpで表記していました。

http://www.data.go.jp/data/dataset/mlit_20140919_2423
https://www.data.go.jp/data/dataset/mlit_20140919_2423

補足情報

(以下2022年2月18日更新)

P.160 5.2以降でforegoのインストールができない場合

Ubuntuにおいて,書籍中で紹介したforegoが,配布元の問題でダウンロードできなくなっています。
Ubuntuでforegoの代替ツールとしてforemanを導入,利用する方法を説明します。

aptでruby-foremanをインストールします。


sudo apt install -y ruby-foreman

インストールができたら,foregoの代替として使えるforemanが実行できるようになります。
書籍中のforegoの部分をforemanに置き換えて実行をお試しください。


foreman run python my_script.py

(以下2021年10月29日更新)

P.212 リスト5.21が動作しない場合

ページの内容が書籍の解説時と変わっていて動作しない可能性があります。
「h3 > a」から「a > h3」に変更するなど,適宜セレクタを変更してお試しください。


import mechanicalsoup

browser = mechanicalsoup.StatefulBrowser()  # StatefulBrowserオブジェクトを作成する。
browser.open('https://www.google.co.jp/')  # open()メソッドでGoogleのトップページを開く。

# 検索語を入力して送信する。
browser.select_form('form[action="/search"]')  # 検索フォームを選択する。
browser['q'] = 'Python'  # 選択したフォームにある name="q" の入力ボックスに検索語を入力する。
browser.submit_selected()  # 選択したフォームを送信する。

# 検索結果のタイトルとURLを抽出して表示する。
page = browser.get_current_page()  # 現在のページのBeautifulSoupオブジェクトを取得する。
for a in page.select('a > h3'):  # select()でCSSセレクターにマッチする要素(Tagオブジェクト)のリストを取得する。
    print(a.text)
    print(browser.absolute_url(a.get('href')))  # リンクのURLを絶対URLに変換して表示する。

(以下2021年10月4日更新)

P.240 リスト5.30の実行

書籍の環境だと,/vagrant以下にDBを作成できない場合があります。リスト5.30ははカレントディレクトリにDBを作成しようとするので,「cd ~」して/home/vagrantに移動しての実行をお試しください。

なお,/home/vagrant以下にも作成できなければ,スクリプト内のDBのパスを'/tmp/geocoding.db'のように書き換える方法をお試しください。

(以下2021年2月24日更新)

P.180 5.3.1でe-Statからダウンロードするデータ

最新の有効求人倍率のデータ形式が書籍中のものから変更されているため動作しません。e-Statからファイルをダウンロードする際は,「~令和2年3月【旧様式】」となっている方のデータを利用してください。

(以下2021年1月29日更新)

P.265 6.2.3 でトップページのトピックス一覧を取得できない

CSSセレクターを次の通りに変更すると取得できます。


Before: ul.topicsList_main a::attr("href")
After: section.topics a::attr("href")

P. 271 6.2.4 でヘッドラインのタイトルと本文を取得できない

CSSセレクターを次の通りに変更すると取得できます。


タイトル
    Before: .tpcNews_title::text
    After: [data-ual-view-type="digest"] > a > p::text
本文
    Before: .tpcNews_summary
    After: [data-ual-view-type="digest"] > p

P.284 6.3.2でIKEA.comの製品情報を取得できない

サイトマップ・製品ページのURLと製品ページのHTMLが変更になっており,リスト6.7 ikea.py の
sitemap_follow 以降を次のように変更すると取得できます。


# サイトマップインデックスからたどるサイトマップURLの正規表現のリスト。
# このリストの正規表現にマッチするURLのサイトマップのみをたどる。
# sitemap_followを指定しない場合は、すべてのサイトマップをたどる。
sitemap_follow = [
    r'prod-ja-JP',  # 日本語の製品のサイトマップのみたどる。
]
# サイトマップに含まれるURLを処理するコールバック関数を指定するルールのリスト。
# ルールは (正規表現, 正規表現にマッチするURLを処理するコールバック関数) という2要素のタプルで指定する。
# sitemap_rulesを指定しない場合はすべてのURLのコールバック関数はparseメソッドとなる。
sitemap_rules = [
    (r'/jp/ja/p/', 'parse_product'),  # 製品ページをparse_productで処理する。
]

def parse_product(self, response):
    # 製品ページから製品の情報を抜き出す。
    yield {
        'url': response.url,  # URL
        'name': response.css('.range-revamp-header-section__title--big::text').get().strip(),  # 名前
        'type': response.css('.range-revamp-header-section__description-text::text').get().strip(),  # 種類
        'price': response.css('.range-revamp-price__integer::text').get().strip(), # 価格(通貨は無し)
    }

P.50 2.4.1のLivedoorお天気WebサービスのAPIが動かず,JSONの検証ができない

(以下2020年8月13日更新)

Livedoorお天気Webサービスのサービス終了で書籍と同一内容ではJSONを返すAPIの検証ができなくなっています。
こちらについては,代替としてJSONを返すWeb APIを利用すれば同等の操作ができます。
例えば,GitHub APIでも実行できます。


# GitHub REST API v3で、Requestsのリポジトリ情報をJSON形式で取得する。
>>> r = requests.get('https://api.github.com/repos/psf/requests')
>>> r.json()
{'id': 1362490, 'node_id': 'MDEwOlJlcG9zaXRvcnkxMzYyNDkw', 'name':
'requests', 'full_name': 'psf/requests', 'private': False, ...

P.149 5.1.1のWikiExtractor.pyのwgetによる取得

プロジェクトの構成の変更により,書籍で案内した方法ではファイルが取得できなくなっていました。下記の通り,以前のバージョンを導入してください。


$ wget https://github.com/attardi/wikiextractor/raw/3162bb6/WikiExtractor.py

P.220 5.6.1のSeleniumの実行がうまくいかない場合

(以下2020年8月5日更新)

ホスト側でchromedriverを起動する際に,以下のように --whitelisted-ips オプションを指定することでエラーが出ずにChromeを自動制御できます。なお, 10.0.2.2 はRemote() の引数で指定するURLのIPアドレスと同じ値です。


chromedriver.exe --port=4444 --whitelisted-ips=10.0.2.2

商品一覧