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

刮痧方式

现在我认为你不应该在管道中这样做,你应该在蜘蛛内部处理它,而不是产生一个项目,而是一个请求,然后产生这个项目。

现在,如果您仍然想在管道中包含一个scrapy Request,您可以执行以下操作:

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

检查我们是否在管道内模拟蜘蛛回调的相同行为。您需要找到一种方法,以便在您想要执行额外请求时始终删除这些项目,并且只需通过额外回调传递那些正在发生的项目。

process_item一种方法是发送不同类型的项目,并在管道内部检查它们:

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