为什么Scrapy会跳过链接?

时间:2018-01-18 03:26:59

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

我是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。我知道我做错了吗?

2 个答案:

答案 0 :(得分:0)

我尝试了你的代码;事实上,它在几秒钟内运行并完成了这条日志消息:

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

让我看看字母链接。结果证明你没有得到你的想法。仔细查看顶部字母链接的URL:它们都是相同的。他们每个人都指向顶级品牌&#34;页面,这是你实际抓取的内容。事实上,没有顶级品牌&#34;以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中不存在这样的链接。如果你想要刮掉那些,那么你就必须自己生成它们并将它们送到干净利落的地方。幸运的是,这很简单 - 你只需要用e替换indexField=e中的$_SESSION["user"] = $user $_SESSION["gender"] = $gender;

答案 1 :(得分:0)

像所有响应代码都对应于[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)
  

确保如果您正在使用并发请求,那么您有足够的代理人