我正在尝试访问一个网站并检查是否没有链接重定向到网站内关闭的页面。由于没有可用的站点地图,我正在使用 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)
我尝试在产量后添加以下行:
item = MytestItem()
item['url'] = link
item['status'] = response.status
yield item
但它让我有一堆重复项,并且没有状态为 404 或 301 的 url。有谁知道我如何获取所有带有状态的网址?
Scrapy 不会返回任何不成功的请求,但如果在请求上设置了errback
,则可以获取它们并在其中一个函数中处理它们。
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
将包含有关失败的确切原因的更多信息,因为它可能是 HTTP 错误(您可以在其中获取响应(,也可能是 DNS 查找错误等(没有响应(。
该文档包含一个示例,如何使用 failure 来确定错误原因和访问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)
您应该在设置中使用HTTPERROR_ALLOW_ALL或在所有请求中设置元键handle_httpstatus_all = True
,请参阅文档以获取更多信息。