この質問は、Force my scrapy spider to stop crawlingと非常によく似ています。しかし、そこに示唆されている解決策はScrapy 1.1.1の日付か、正確には関連していない。 スパイダーが特定のURLに達すると、スパイダーを閉じます。メディアプロジェクトなどのニュースサイトをクロールするときは、これが絶対必要です。指定されたURLを満たしたときにスパイダーが止まる
CLOSESPIDER_TIMEOUT
CLOSESPIDER_ITEMCOUNT
CLOSESPIDER_PAGECOUNT
CLOSESPIDER_ERRORCOUNT
のうち、アイテム数とページ数のオプションは近いですが、ページ数やアイテム数がわからないため、十分ではありません。
例外は仕事をしているようですが、今のところそれはちょっと奇妙な方法で行います。私は“Learning Scrapy”の教科書に従い、私のコードの構造は本の中のもののように見えます。 items.py
で
私が項目のリストを作る:私はクモがdef parse()
内の各インデックスページを解析し、処理するためのページを取るdef start_requests()
メソッドを使用myspider.py
で
class MyProjectItem(scrapy.Item):
Headline = scrapy.Field()
URL = scrapy.Field()
PublishDate = scrapy.Field()
Author = scrapy.Field()
pass
、および各項目のXPathを指定しますdef parse_item()
中:
class MyProjectSpider(scrapy.Spider):
name = 'spidername'
allowed_domains = ['domain.name.com']
def start_requests(self):
for i in range(1,3000):
yield scrapy.Request('http://domain.name.com/news/index.page'+str(i)+'.html', self.parse)
def parse(self, response):
urls = response.xpath('XPath for the URLs on index page').extract()
for url in urls:
# The urls are absolute in this case. There’s no need to use urllib.parse.urljoin()
yield scrapy.Request(url, callback=self.parse_item)
def parse_item(self, response):
l = ItemLoader(item=MyProjectItem(), response=response)
l.add_xpath('Headline', 'XPath for Headline')
l.add_value('URL', response.url)
l.add_xpath ('PublishDate', 'XPath for PublishDate')
l.add_xpath('Author', 'XPath for Author')
return l.load_item()
raise CloseSpider(reason='some reason')
例外がdef parse_item()
に配置されている場合、それはまだfinallその前にアイテムの数を削りますyが停止します。
if l.get_output_value('URL') == 'http://domain.name.com/news/1234567.html':
raise CloseSpider('No more news items.')
それは、特定のURLに達したときに停止するdef parse()
方法に置かれています場合、それはその特定のURLが含まれているインデックスページからのみ最初の項目グラブの後に停止します。
def parse(self, response):
most_recent_url_in_db = 'http://domain.name.com/news/1234567.html '
urls = response.xpath('XPath for the URLs on index page').extract()
if most_recent_url_in_db not in urls:
for url in urls:
yield scrapy.Request(url, callback=self.parse_item)
else:
for url in urls[:urls.index(most_recent_url_in_db)]:
yield scrapy.Request(url, callback=self.parse_item)
raise CloseSpider('No more news items.')
をたとえば、5つのインデックスページ(それぞれ25アイテムのURLを持っています)とmost_recent_url_in_db
が4ページにある場合は、1〜3ページのすべてのアイテムと4ページの最初のアイテムだけを持つことになります。スパイダーは止まる。 most_recent_url_in_db
がリストの番号10の場合、インデックスページ4の項目2-9はデータベースに表示されません。
crawler.engine.close_spider()
で示唆されている「ハッキー」のトリックや、多くの場合にはHow do I stop all spiders and the engine immediately after a condition in a pipeline is met?で共有されているものが動作していないようです。
このタスクを正しく完了するにはどのような方法が必要ですか?
ジュリア、このソリューションは素晴らしいです!それは非常にエレガントで、特に初心者にとっては理解しやすいです。私はそれが多くの人々を助けると確信しています。さらに、あなたはすべてのコードを書いています。私はそれに何かを加える必要さえない。これは素晴らしいことではありませんか?)本当にありがとうございました! –