【问题标题】:Why is Scrapy skipping over links?为什么 Scrapy 会跳过链接?
【发布时间】:2018-01-18 03:26:59
【问题描述】:

我是 Python 的新手,我正在尝试用 Scrapy 对抗亚马逊。我正在尝试从

获取项目名称和计数

https://www.amazon.ca/gp/search/other/ref=sr_in_a_C?rh=i%3Akitchen%2Cn%3A2206275011%2Cn%3A%212206276011%2Cn%3A2224068011%2Cn%3A6647367011%2Cn%3A6647368011&page=2&bbn=6647368011&pickerToList=lbr_brands_browse-bin&indexField=a&ie=UTF8&qid=1515439041

这是我的 Python 代码:

import scrapy

class ToScrapeCSSSpider(scrapy.Spider):
    name = "toscrapeamazon-css"
    start_urls = [
        "https://www.amazon.ca/gp/search/other/ref=sr_in_a_-2?rh=i%3Akitchen%2Cn%3A2206275011%2Cn%3A%212206276011%2Cn%3A2224068011%2Cn%3A6647367011%2Cn%3A6647368011&page=2&bbn=6647368011&pickerToList=lbr_brands_browse-bin&indexField=a&ie=UTF8&qid=1515436664",
    ]

    def parse(self, response):
        for item in response.css("span.a-list-item"):
            yield {
                "item_name": item.css("span.refinementLink::text").extract_first(),
                "item_cnt": item.css("span.narrowValue::text").extract_first()
            }

        next_page_url = response.css("span.pagnLink > a::attr(href)").extract_first()
        if next_page_url is not None:
            yield scrapy.Request(response.urljoin(next_page_url))

我能够获得我想要的大部分数据,但我没有得到任何关于字母 D、E、I、J 的数据。知道我做错了什么吗?

【问题讨论】:

    标签: python-3.x web-scraping scrapy


    【解决方案1】:

    我试过你的代码;它在几秒钟内运行并以这条日志消息结束的事实:

    Filtered duplicate request: <GET https://www.amazon.ca/gp/search/other?ie=UTF8&page=2&pickerToList=lbr_brands_browse-bin&rh=n%3A6647368011>

    引导我查看字母链接。事实证明,你并没有得到你认为的那样。仔细查看顶部字母链接的 URL:它们都是一样的。他们每个人都指向“顶级品牌”页面,这就是您实际抓取的内容。碰巧没有以 D、E、I 或 J(或 Q、Y 或 Z)开头的“顶级品牌”。字母链接上必须有一个 javascript 监听器,它会拦截点击并将您重定向到特定于字母的 URL,如下所示:

    https://www.amazon.ca/gp/search/other/ref=sr_in_e_A?rh=i%3Akitchen%2Cn%3A6647368011&page=2&pickerToList=lbr_brands_browse-bin&indexField=e&ie=UTF8&qid=1516249484

    因为 HTML 中不存在此类链接。如果你想抓取这些,你将不得不自己生成它们并将它们提供给 scrappy。幸运的是,这很容易 - 您只需将 indexField=e 中的 e 替换为其他字母即可。

    【讨论】:

      【解决方案2】:

      像所有响应代码对应 [404, 403, 302, 503, 502, 400, 407] 一样处理您的错误,并按如下方式发出另一个请求。

           if response.status in [404,403, 302, 503, 502, 400, 407]:
              yield Request(url=response.request.url, callback=self.parse,dont_filter=True)
      

      确保您在使用并发请求时有足够的代理

      .

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-04-17
        • 1970-01-01
        • 2013-05-08
        • 1970-01-01
        • 1970-01-01
        • 2021-11-13
        • 2017-11-10
        • 2015-02-26
        相关资源
        最近更新 更多