使用Scrapy进行爬网 - 不处理或不允许HTTP状态代码?

时间:2017-10-14 16:20:00

标签: python scrapy web-crawler scrapy-spider

我想获得类别https://tiki.vn/dien-thoai-may-tinh-bang/c1789

中的产品标题,链接,价格

但它失败了#34; HTTP状态代码未被处理或不被允许" https://i.stack.imgur.com/KCFw2.jpg

我的档案: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()

请帮帮我!!!!谢谢!

4 个答案:

答案 0 :(得分:14)

TL;博士

基于scrapy的用户代理阻止您。

您有两种选择:

  1. 授予网站的愿望,不要刮掉它们,或
  2. 更改您的用户代理
  3. 我假设你想选择2。

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

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

    详细的错误分析

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

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

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

    enter image description here

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

    需要进一步调查

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

    我想抓取一个网站,它在我的家用电脑上工作得很好,但根本没有回复(甚至不是404)来自我服务器的任何请求(scrapy,wget,curl,......)。

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

    • 您可以从家用电脑上访问该网站(并获得状态码200)吗?
    • 如果你从家用电脑上运行scrapy会怎样?还是404?
    • 尝试从运行scrapy的服务器加载网站(例如使用wget或curl)

    您可以使用wget来获取它:

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

    wget会发送自定义用户代理,因此如果此命令不起作用(可以从我的电脑上执行),您可能希望将其设置为web browser's user-agent

    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的用户代理是问题所在。 According to the documentation,除非您自己设置,否则scrapy会使用Scrapy/VERSION (+http://scrapy.org)作为用户代理。它们很可能会根据用户代理阻止您的蜘蛛。

    因此,您必须转到scrapy项目中的settings.py并在那里查找设置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.
    

答案 1 :(得分:0)

除了Aufziehvogel用户代理更改外,还请参考http错误代码。在您的情况下,http错误代码为404,表示客户端错误(NOT FOUND)。

如果网站需要经过身份验证的会话来抓取内容,则http错误代码可能是401,它指示了CLIENT ERROR(UNAUTHORIZED

答案 2 :(得分:0)

除了其他两个很好的答案,请尝试以下操作:

  1. 'Redirect_enabled':的值设置为true
  2. 使用httpshttp协议。
  3. 使用或删除www前缀。

答案 3 :(得分:0)

尝试使用以下命令更改用户代理:

scrapy shell -s USER_AGENT='custom user agent' 'http://www.example.com'

有时,网站会阻止特定的用户代理,以防止其爬行并面临太多请求。然后,您可以使用view(response)命令查看它是否有效。

对于基于类的实现,@Aufziehvogel讲述的故事非常完整!