10
1

More than 5 years have passed since last update.

scrapyでstart_urlsやrulesにコマンドライン引数を渡す

Last updated at Posted at 2018-12-12

はじめに

この記事はMicroAd Advent Calendar 2018の13日目の記事です。
自分が自然言語処理を行うためのデータを集めようとクローリング&スクレイピングしていた時にめっちゃ詰まった部分があったので、その解決Tipsをまとめようと思います。

scrapyを使ってみて

自分はついこの前までscrapyはおろかクローリングもスクレイピングも全く知らないという状態で一から使い始めたのですが、とても便利でした。

  • 全体的にPython初心者でも書きやすい
  • settingsを追加すれば意図通り上手く動作してくれる
  • Spiderのクラスを書き換えれば色々なページに対応可能なのが楽で良い

などが率直な意見です。

こんな使い方がしてみたい!

scrapyを使っていると、こんなことを思いました。
CrawlSpiderに渡すstart_urlsとかrulesにコマンドライン引数を渡せないかな...
そのために色々と検索して試行錯誤した結果、以下のような解決策が見つかりました。

  • start_urlsはSpiderのクラスで_init_中に設定してやれば良い
  • rulesは_init_中に設定してやったのち、以下のコードを付け加える
self._compile_rules()

この一文を忘れると設定したrulesが反映されません!

実際に試してみよう

クローラーとして以下のようなコードを書いてみます。
今回は弊社のエンジニアブログを使用します。
インフラカテゴリの4記事中、IoTの記事だけの抽出を目指します。
なお、scrapyのほかにbeautifulsoup4とreadabilityも併用しました。

microad.py
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from scrapy.crawler import CrawlerProcess
from bs4 import BeautifulSoup
from readability.readability import Document

from microad.items import MicroadItem

class MicroadCrawlSpider(CrawlSpider):
    name = 'microad_crawl'
    allowed_domains = ['developers.microad.co.jp']

    '''
        クローラーの初期化
    '''
    def __init__(self, *args, **kwargs):
        super(MicroadCrawlSpider, self).__init__(*args, **kwargs)
        # start_urlsを設定
        self.start_urls = ['https://developers.microad.co.jp/archive/category/'+self.search_word]
        # クローラーのリンクの辿り方を設定
        self.rules = (
            Rule(LinkExtractor(allow=r'/entry/'+self.year_month_day), follow=True, callback = 'parse_texts'),
        )
        # 上記で設定した項目をコンパイル
        self._compile_rules()

    '''
        本文を取り出すメソッド
    '''
    def parse_texts(self, response):
        item = MicroadItem()
        document = Document(response.text)

        item['text'] = BeautifulSoup(document.summary(), "lxml").get_text()

        yield item

これを以下のコマンドで実行します。

$ scrapy crawl microad_crawl -a search_word='インフラ' -a year_month_day='2018/06/21'

すると、以下のような結果が得られました。

{'text': '\n'
         'こんにちは。マイクロアドでインフラエンジニアとして勤務している伊東です。\n'
         '今日はインフラエンジニア視点で導入してみた社内 IoT、間接的な業務効率改善の話をいろいろ脱線しながらユルくご紹介したいと思います。\n'
         ...
         (中略)
         ...
         '心配していた電池も8ヶ月程度は持ちそうです。これなら運用負荷も許容範囲でしょう。さて次はなにをつくろうか\n'
         '※電波送受信に関わる部品はすべて Mono Wireless 純正品を組み合わせており電波法上問題はありません。\n'
         '\xa0\n'
         '\n'
         '\n'}

他の記事も表示されません。
大成功です!!!
あとは邪魔な改行コードなどを除けば処理ができますね。

まとめ

今回はscrapyのTipsをご紹介しました。
この記事では1つのページだけを抽出しましたが、例えば検索キーワードをコマンドラインからrulesに設定するなどの工夫をしたらもっと使い方が広がりそうです。
ぜひ試してみてください!

10
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
1