Scrapy:HTTP 状态码未处理或不允许?

新手上路,请多包涵

我想获得类别 https://tiki.vn/dien-thoai-may-tinh-bang/c1789 中的产品名称、链接、价格

但它失败了“HTTP 状态代码未处理或不允许”:

错误日志

我的文件:spiders/tiki.py

 import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule

from stackdata.items import StackdataItem

class StackdataSpider(CrawlSpider):
    name = "tiki"
    allowed_domains = ["tiki.vn"]
    start_urls = [
        "https://tiki.vn/dien-thoai-may-tinh-bang/c1789",
    ]

    rules = (
        Rule(LinkExtractor(allow=r"\?page=2"),
             callback="parse_item", follow=True),
    )

    def parse_item(self, response):
        questions = response.xpath('//div[@class="product-item"]')

        for question in questions:
            question_location = question.xpath(
                '//a/@href').extract()[0]
            full_url = response.urljoin(question_location)
            yield scrapy.Request(full_url, callback=self.parse_question)

    def parse_question(self, response):
        item = StackdataItem()
        item["title"] = response.css(
            ".item-box h1::text").extract()[0]
        item["url"] = response.url
        item["content"] = response.css(
            ".price span::text").extract()[0]
        yield item

文件:items.py

 import scrapy

class StackdataItem(scrapy.Item):
    title = scrapy.Field()
    url = scrapy.Field()
    price = scrapy.Field()

请帮我!!!!谢谢!

原文由 gait 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 690
1 个回答

tl;博士

您正在根据 scrapy 的用户代理被阻止。

你有两个选择:

  1. 满足网站的愿望,不要抓取它们,或者
  2. 更改您的用户代理

我假设您想选择选项 2。

转到您的 settings.py 在您的 scrapy 项目中并将您的用户代理设置为非默认值。您自己的项目名称(它可能不应包含单词 scrapy )或标准浏览器的用户代理。

 USER_AGENT='my-cool-project (http://example.com)'

详细错误分析

我们都想学习,所以这里解释一下我是如何得到这个结果的,以及如果你再次看到这种行为你可以做什么。

网站 tiki.vn 似乎为您的蜘蛛的所有请求返回 HTTP 状态 404 。您可以在屏幕截图中看到,您对 /robots.txt/dien-thoai-may-tinh-bang/c1789 的请求都得到了 404。

404 表示“未找到”,Web 服务器使用它来表明 URL 不存在。但是,如果我们手动检查相同的站点,我们可以看到两个站点都包含有效内容。现在,从技术上讲,这些网站可能会同时返回内容和 404 错误代码,但我们可以通过浏览器(例如 Chrome 或 Firefox)的开发人员控制台来检查这一点。

在此处输入图像描述

在这里我们可以看到 robots.txt 返回了一个有效的 200 状态码。

有待进一步调查

许多网站试图限制抓取,因此他们试图检测抓取行为。因此,他们会查看一些指标并决定是向您提供内容还是阻止您的请求。我假设这正是您正在发生的事情。

我想抓取一个网站,该网站在我的家用 PC 上运行良好,但根本没有响应(甚至没有 404)来自我的服务器(scrapy、wget、curl 等)的任何请求。

您必须采取后续步骤来分析此问题的原因:

  • 您可以从家用 PC 访问该网站吗(您是否获得状态代码 200)?
  • 如果你从家里的 PC 上运行 scrapy 会发生什么?还是404?
  • 尝试从运行 scrapy 的服务器加载网站(例如使用 wget 或 curl)

您可以像这样使用 wget 获取它:

 wget https://tiki.vn/dien-thoai-may-tinh-bang/c1789

wget 确实会发送自定义用户代理,因此如果此命令不起作用(它在我的 PC 上起作用),您可能希望将其设置为 Web 浏览器的用户代理

 wget -U 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36' https://tiki.vn/dien-thoai-may-tinh-bang/c1789

这将帮助您找出问题是否出在服务器上(例如,他们阻止了 IP 或整个 IP 范围),或者您是否需要对您的蜘蛛进行一些修改。

检查用户代理

如果它适用于您的服务器的 wget,我怀疑 scrapy 的用户代理是问题所在。 根据文档,scrapy 确实使用 Scrapy/VERSION (+http://scrapy.org) 作为用户代理,除非你自己设置它。他们很可能会根据用户代理阻止您的蜘蛛。

所以,你必须去 settings.py 在你的 scrapy 项目中寻找设置 USER_AGENT 那里。现在,将其设置为不包含关键字 scrapy 的任何内容。如果你想变得友善,请使用你的项目名称 + 域,否则使用标准浏览器用户代理。

不错的变体:

 USER_AGENT='my-cool-project (http://example.com)'

不太好(但在抓取中很常见)变体:

 USER_AGENT='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'

事实上,我能够从我的本地 PC 使用此 wget 命令验证它们是否阻止了用户代理:

 wget -U 'Scrapy/1.3.0 (+http://scrapy.org)' https://tiki.vn/dien-thoai-may-tinh-bang/c1789

这导致

--2017-10-14 18:54:04--  https://tiki.vn/dien-thoai-may-tinh-bang/c1789
Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt'
Resolving tiki.vn... 203.162.81.188
Connecting to tiki.vn|203.162.81.188|:443... connected.
HTTP request sent, awaiting response... 404 Not Found
2017-10-14 18:54:06 ERROR 404: Not Found.

原文由 aufziehvogel 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏