Scrapyのコツ
Scrapyを作ってていくつかコツをつかんだ気がする。といっても処理側の話なので、xpathをマスターしないことにはScrapyが作れないことには変わりない。
Spiderのコツ
itemをitemクラスに格納する際にはyieldをうまく使うといい。
前回やったRSSのようにデータが繰り返しの構造になっている場合には、forループを回している最中で処理がyieldに到達するとpipelineへと処理が移行する。pipelineの処理が終わると、またSpiderにおいてforループの続きが行われる。
前回記事ではpipelineに関する処理は省略したが、SpiderとpipelineはSpiderでitemにデータを全部いれてからpipelineでforループを使って処理をしていた
- 変更前
# your Spider item['title'] =response.xpath('//item/title/text()').extract() item['link'] =response.xpath('//item/link/text()').extract() yield item
# your pipeline title = item['title'] link = item['link'] for (t, l) in zip(title, link): print("title", t) print("link", l)
これをSpiderでforループを回して途中でyieldするようにして、pipelineではforループを書かないように変更した。
- 変更後
# your Spider rss = response.xpath('//item') for sel in rss: item = HatenaHotentryItem() item['title'] = sel.xpath('title/text()').extract()[0] item['link'] = sel.xpath('title/text()').extract()[0] yield item
# your pipeline title = item['title'] link = item['link'] print("title", title) print("link", link)
これでforループの途中でpipelineに処理が移行し、pipelineがitemを使って何かしらの処理ができるようになる。どっちでforループを書くのかってだけといえばそのとおり。
pipelineのコツ
コツってほどでもないけど、上のSpiderに合わせて変更をする。pipelineではSpiderのライフサイクルに合わせて処理の定義ができる。
Item Pipeline — Scrapy 1.3.0 documentation
具体的にはSpider開始時、処理中と終了時の処理を定義できる。たとえば、Spider開始時にRDBとのコネクションを張って、Spider終了時にコネクションを切るといった事もできる。
class YourPipeline(object): def __init__(self): # いわゆるinit。pipelineがインスタンス化されたときに呼び出される # pipeline特有のものではなくpython標準なので、特に解説するようなことはない def open_spider(self, spider): # スパイダーが起動したときに呼び出される # DBへのコネクションを張ったりとか def process_item(self, item, spider): # スパイダーがyieldした時に呼び出される # itemを使って具体的に処理をする def close_spider(self, spider): # スパイダーが終了したときに呼び出される # トランザクションをcommitしたりDBをcloseしたりとか
処理を変えるとoutputするjsonのデータ構造も変わるので、好きなほうに変えるといいと思う。jsonがどういった構造のほうが扱いやすいかで決めたらいい。