5

このようなスクレイピングされたアイテムがあるとします

{
    name: "Foo",
    country: "US",
    url: "http://..."
}

パイプラインで、URL に GET リクエストを送信し、content_type や status などのヘッダーを確認したいと考えています。ヘッダーが特定の条件を満たしていない場合、アイテムをドロップしたい。お気に入り

class MyPipeline(object):
    def process_item(self, item, spider):
        request(item['url'], function(response) {
           if (...) {
             raise DropItem()
           }
           return item
        }, function(error){ 
            raise DropItem()
        })

このような臭いは、パイプラインでは不可能です。どう思いますか?これを達成する方法はありますか?

くも:

import scrapy
import json

class StationSpider(scrapy.Spider):
    name = 'station'
    start_urls = ['http://...']

    def parse(self, response):
        jsonResponse = json.loads(response.body_as_unicode())
        for station in jsonResponse:
            yield station
4

1 に答える 1

9

簡単な方法

import requests

def process_item(self, item, spider):
    response = requests.get(item['url'])
    if r.status_code ...:
        raise DropItem()
    elif response.text ...:
        raise DropItem()
    else:
        return item

スクレイピーな方法

パイプライン内でこれを行うべきではないと思います。アイテムを生成するのではなく、リクエストを生成してからアイテムを生成するスパイダー内で処理する必要があります。

それでもパイプライン内にスクレイピーなリクエストを含めたい場合は、次のようにすることができます。

class MyPipeline(object):

    def __init__(self, crawler):
        self.crawler = crawler

    @classmethod
    def from_crawler(cls, crawler):
        return cls(crawler)

    def process_item(self, item, spider):
        ...
        self.crawler.engine.crawl(
                    Request(
                        url='someurl',
                        callback=self.custom_callback,
                    ),
                    spider,
                )

        # you have to drop the item, and send it again after your check
        raise DropItem()
    # YES, you can define a method callback inside the same pipeline
    def custom_callback(self, response):
        ...
        yield item

パイプライン内のスパイダー コールバックと同じ動作をエミュレートしていることを確認します。追加のリクエストを実行したい場合は常にアイテムをドロップし、追加のコールバックによって存在するアイテムを渡す方法を見つける必要があります。

1 つの方法として、さまざまな種類のアイテムを送信しprocess_item、パイプライン内でそれらをチェックすることができます。

def process_item(self, item, spider):
    if isinstance(item, TempItem):
        ...
    elif isinstance(item, FinalItem):
        yield item
于 2016-07-19T21:15:25.103 に答える