【问题标题】:Can't get all http requests in Scrapy无法在 Scrapy 中获取所有 http 请求
【发布时间】:2017-11-13 07:59:01
【问题描述】:

我正在尝试访问一个站点并检查是否没有链接重定向到该站点内的已关闭页面。由于没有可用的站点地图,我使用Scrapy 来抓取站点并获取每个页面上的所有链接,但我无法让它输出包含找到的所有链接及其状态代码的文件。我用来测试代码的网站是quotes.toscrape.com,我的代码是:

from scrapy.spiders import Spider
from mytest.items import MytestItem
from scrapy.http
import Request
import re
class MySpider(Spider):
    name = "sample"
    allowed_domains   = ["quotes.toscrape.com"]
    start_urls = ["http://quotes.toscrape.com"]
    def parse(self, response):
        links = response.xpath('//a/@href').extract()
\# We stored already crawled links in this list
        crawledLinks = []
        for link in links:
\# If it is a proper link and is not checked yet, yield it to the Spider
        if link not in crawledLinks:
             link = "http://quotes.toscrape.com" + link
             crawledLinks.append(link)
             yield Request(link, self.parse)

我尝试在 yield 之后添加以下行:

item = MytestItem()
item['url'] = link
item['status'] = response.status
yield item

但它给我带来了一堆重复,没有状态为 404 或 301 的 url。有谁知道我如何获得所有状态为 url 的 URL?

【问题讨论】:

    标签: python scrapy


    【解决方案1】:

    默认情况下,Scrapy 不会返回任何不成功的请求,但如果您设置了errback on the request,您可以在其中一个函数中获取并处理它们。

    def parse(self, response):
        # some code
        yield Request(link, self.parse, errback=self.parse_error)
    
    def parse_error(self, failure):
        # log the response as an error
    

    参数failure 将包含more information on the exact reason 表示失败,因为它可能是HTTP 错误(您可以在其中获取响应),也可能是DNS 查找错误等(没有响应)。

    文档包含一个示例,如何使用失败来确定错误原因并访问Response(如果有):

    def errback_httpbin(self, failure):
        # log all failures
        self.logger.error(repr(failure))
    
        # in case you want to do something special for some errors,
        # you may need the failure's type:
    
        if failure.check(HttpError):
            # these exceptions come from HttpError spider middleware
            # you can get the non-200 response
            response = failure.value.response
            self.logger.error('HttpError on %s', response.url)
    
        elif failure.check(DNSLookupError):
            # this is the original request
            request = failure.request
            self.logger.error('DNSLookupError on %s', request.url)
    
        elif failure.check(TimeoutError, TCPTimedOutError):
            request = failure.request
            self.logger.error('TimeoutError on %s', request.url)
    

    【讨论】:

    • 谢谢,我无法记录 404 错误,但我认为这是因为 url 是 robots.txt 文件。你知道我如何在文件中获取 url 和响应吗? Scrapy 在运行时已经向我展示了,但它不会使用它们创建文件,即使使用 -o file -t type。
    • 最简单的方法是使用feed exporters。您只需选择写入方法(基于文件)和格式(CSV、JSON、...)。选项FEED_FORMATFEED_URI 必须添加到settings.py。对于基于文件的输出,您可以设置类似FEED_FORMAT="file:///tmp/export.csv"
    【解决方案2】:

    您应该在设置中使用HTTPERROR_ALLOW_ALL 或在所有请求中设置元键handle_httpstatus_all = True,请参阅文档以获取更多信息。

    【讨论】:

      猜你喜欢
      • 2017-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-18
      • 1970-01-01
      • 2013-12-03
      • 1970-01-01
      相关资源
      最近更新 更多