スクレイピングネタです。
Scrapy は Spider の perse()
メソッドの中で新しい Request オブジェクトを yield
してあげるだけで、次々に URL を辿ってクローリングしていけるので便利ですね。
例えば、response.xpath("//a/@href").extract()
とかすればページの中のリンクを取得するのも容易です。
ただし、取得したリンクの href
が全て絶対パスで書かれている保証はありません。
もしも、相対パスで書かれていた場合は(そういう場合は多いでしょう)、相対パスを解決して絶対パスにしてあげなくてはいけません。
Python で相対パスの解決をしようと思えば、urlparse
モジュールの urljoin()
を使うのが普通です。
が、Scrapy には urlparse.urljoin()
相当のメソッドが最初から組み込まれているので、そちらを利用するのが便利です。
サイトの全ページを辿って <title>
を取得する Spider を例に見ると、
# -*- coding: utf-8 -*- import scrapy class SampleSpider(scrapy.Spider): name = "sample" allowed_domains = ["example.com"] start_urls = [ "http://example.com/", ] def parse(self, response): # <title> タグの中を取得して返す title = response.xpath("//title/text()").extract_first() yield { "url": response.url, "title": title, } for href in response.xpath('//a/@href').extract(): # href を urljoin() で絶対パスに変換 next_url = response.urljoin(href) # 新しい Request オブジェクトを返すことで、その URL が続いてクロールされる yield scrapy.Request(next_url)
for文の中で response.urljoin(href)
としています。
response.urljoin()
は現在の URL をベースに相対パスを解決するので、これで urlparse.urljoin(response.url, href)
と書いたときと同じ処理になります。
シンプルで、分かりやすいですね。
私からは以上です。