satewn-memo

だいたい技術っぽい雑記

Python3でWebスクレイピング・クローリング入門:Scrapy実践編

前回の入門編の続きです。 今回はScrapyの公式ドキュメントに沿って、簡単なチュートリアルを解説していきます。

Scrapy導入

MacもしくはLinuxでpipが使える環境にあるなら、いつも通り

pip install scrapy

で問題ありません。もしエラーが出たら

pip install twisted

でtwistedを導入してからやり直してください。

Windowsでまともにインストールしようとすると幾つもライブラリを追加しなければならなかったり、幾つもパスを通さなければいけなかったりと面倒ですが、Anacondaに一任すれば問題なかった。Anaconda導入については他記事に任せます。

activate py35con

コマンドプロンプト上記を入力し、Anacondaのcondaで作ったPython3.5環境に入ります。 後は以下のコマンドであっさりと導入できます。

conda install -c conda-forge scrapy

公式ドキュメントにも、Windowsを使用している場合はcondaで導入するのが一番良い方法だと書かれています。

Scrapyによるスクレイピングのテスト

適当な作業用ディレクトリに移動し、以下のコマンドを入力するとScrapyのプロジェクトが作成されます(tutorialはプロジェクト名なのでなんでもよい)。

scrapy startproject tutorial

次に、Spiderを作成します。Spiderというのはどのページの情報をどのように抽出するかを定義するもの。 以下のようなサンプルファイルを用意し、quotes_spider.pyという名前で/tutorial/tutorial/spiderディレクトリに保存します。

import scrapy

class QuotesSpider(scrapy.Spider):
    name = "quotes"
    start_urls = [
'http://quotes.toscrape.com/page/1/',
'http://quotes.toscrape.com/page/2/',
    ]

    def parse(self, response):
        page = response.url.split("/")[-2]
        filename = 'quotes-%s.html' % page
        with open(filename, 'wb') as f:
            f.write(response.body)

各自で作成するSpiderクラスはscrapy.Spiderを継承している必要があります。 このサンプルではquotesというサイトのページを二つ取得しますが、抽出処理は行っておらず、ただ指定されたURLのHTMLコピーをローカルに作成するだけのものです。 Spiderを用意したら以下のコマンドで起動できます(上記コードのnameで指定した名前を使う)。

scrapy crawl quotes

コマンドラインにログが出力され、正しく終了していればtutorialディレクトリにquotes-1.htmlとquotes-2.htmlが作成されているはずです。 これらのファイルは元のサイトのHTMLそのままですが、cssが無いためブラウザで開いても見た目が良くありません。

先ほどのサンプルで、parseメソッドを書き換えることによってデータの抽出が可能です。

    def parse(self, response):
        for quote in response.css('div.quote'):
            yield {
                'text': quote.css('span.text::text').extract_first(),
                'author': quote.css('span small::text').extract_first(),
                'tags': quote.css('div.tags a.tag::text').extract(),
            }

このコードの動作を簡単に説明すると、

  • quoteというクラス名を持つすべてのdiv要素の子に対して
  • textというクラス名を持つspan要素のテキストを抽出し
  • span要素の子のsmall要素のテキストを抽出し
  • tagsというクラス名を持つdiv要素の子でかつ、tagというクラス名を持つa要素のテキストを抽出し
  • 辞書に格納する

ちなみにexctract_firstメソッドを用いると、条件にマッチした要素が存在しなくてもNoneを返してくれるためエラーになりません。 このようにSpiderを変更し、コマンドプロンプト

scrapy crawl quotes -o quotes.json

と入力してあげると、所望の辞書がjsonとして出力されます。 この他にも条件に合うリンクを辿り、その先でデータの抽出を行ったり、辿る深さなども設定できます。 これらのオプションは初めからScrapyに用意されており、複雑な記述をする必要はありません。

Scrapy 実行の流れ

Scrapyのアーキテクチャ図を以下に示します(こちらの記事から拝借)。

Scrapy Architecture

Spiderが実行された時の処理の流れは以下の通り。

  1. まず、start_urlsに含まれるURLを指すRequestオブジェクトがSpiderからSchedulerに渡される
  2. SchedulerはRequestをキューに溜める
  3. キューに追加されたオブジェクトは順にDownloaderに渡される
  4. DownloaderはWebページを取得し、Responseオブジェクトに格納し、それをSpiderに渡す
  5. Responseを引数としてparse()が呼び出される
  6. SpiderからItemや辞書が出力された場合はFeed Exporterへ、Requestが出力された場合はSchedulerに渡される
  7. 以上を繰り返し、キューからRequestがなくなれば実行完了

図にある各種ミドルウェアは、DownloaderやResponse, Requestに対する処理を拡張する役割を持っています。

おわりに

かなり駆け足になってしまいましたが、公式のチュートリアルに沿って簡単なスクレイピングを解説してきました。この短いコードだけではScrapyの強力さを説明しきれないので、是非いろいろとオプションなり拡張なり試してもらえると、楽しくスクレイピングが出来るはずです。

Python3でWebスクレイピング・クローリング入門:基礎知識編

※もし間違っている部分がございましたら修正しますので、コメント等でお知らせ頂けると幸いです。

スクレイピングって、すごくワクワクする技術の割にそこまで取沙汰されていないような気がします。なので今回は、「なんかスクレイピング興味ある! やってみたい!」という方向けに、簡単な入門記事を基礎知識編・入門編に分けて書いてみることにしました。Pythonを選んだのは個人的にスクレイピングに向いてて書きやすいと思ったため(ライブラリも沢山ある)。

言葉の定義

そもそもスクレイピングって何ぞや? クローリングって言葉も聞くけどどう違うの? という部分について。

  • クローリング・・・Webサイトのリンクを辿り、その内容を収集すること
  • スクレイピング・・・収集されたデータ(HTMLなど)を解析、抽出、整形、再利用すること

例えば、ある特定のWebページから情報を抜き出してゴニョゴニョするのがスクレイピングです。一方であるドメイン全体や、不特定多数のWebページからどんどんリンクを辿っていくのがクローリングとなります。Googleなんかはスクレイピング・クローリングの親玉ですね。

環境について

Python向けのスクレイピング・クローリングのためのライブラリは数多くあり、単純な処理であればPython標準のモジュールでも対応できます。

ライブラリ名 用途
requests Webページの取得を行う。
BeautifulSoup HTMLを解析し、目的のデータを抽出できる。
Selenium フォームへの入力やクリックなど、ブラウザの操作を自動で行える。Javascriptレンダリングされているページでも対応できるのが強み。
Scrapy スクレイピングのためのフレームワーク。例えばrequestsとBeautifulSoupを組み合わせてやることをScrapyだけで行える。

Scrapyについて

Scrapyはここ最近人気上昇中のフレームワークです。情報も豊富で使い勝手も良さそうなのですが、ブラウザの自動操作は出来ません。 自動操作をしたい場合は、ScrapyとSelenuimを組み合わせて使う必要があります。

フレームワークであるScrapyを使うメリットをこちらから引用します。

Scrapyを使わなくても、Seleniumだけでもスクレイピングはできるんだけど、

  • 並行処理で複数ページをスクレイピングしてくれる(マルチスレッド?プロセス?)、
  • 何ページクロールしたかとか、エラーは何回起こったかとか、ログをいい感じにまとめてくれる、
  • クロール対象ページの重複を回避してくれる、
  • クロールの間隔とか、いろんな設定オプションを提供してくれる、
  • CSSXPathを組み合わせて、DOMから情報を抜ける(組み合わせが結構便利!)、
  • クロール結果を、JSONとかXMLで吐き出せる、
  • いい感じのプログラム設計でクローラーを書ける(下手に自分で設計するより良いと思う)、

など、思いつくScrapyを使うメリットはこんな感じ。

次回は実際にScrapyを使って簡単なスクレイピングチュートリアルを進めていきます。

ネットワーク系・OS系の国際カンファレンスまとめ

私用ですが。特にOS系については全く網羅しきれていない自信あり。


【OS系】

USENIX OSDI

Operating Systems Design and Implementation

ACM ASPLOS

Architectural Support for Programming Languages and Operating Systems

ACM SOSP

Symposium on Operating Systems Principles


【ネットワーク系】

ACM SIGCOMM

Special Interest Group on Data Communication

ACM SIGMETRICS

Special Interest Group on Measurement and Evaluation

ACM SIGKDD

Special Interest Group on Knowledge Discovery and Data Mining

IEEE INFOCOM

International Conference on Computer Communications

USENIX NSDI

Network Systems Design and Implementation


【分野が広く、OSやネットワークも含むもの】

USENIX ATC

Annual Technical Conference

EuroSys

The European Conference on Computer Systems