Scrapy-刮刮每页,但刮擦环绕并刮擦前x页

时间:2020-02-18 20:46:43

标签: python web-scraping scrapy

class HomedepotcrawlSpider(CrawlSpider):

    name = 'homeDepotCrawl'
    #allowed_domains = ['homedepot.com']
    start_urls =['https://www.homedepot.com/b/Appliances/ZLINE-Kitchen-and-Bath/N-5yc1vZbv1wZhsy?experienceName=default&Nao=0']

    def parse(self, response):

        for item in self.parseHomeDepot(response):
            yield item

        next_page_url = response.xpath('//link[@rel="next"]/@href').extract_first()
        if next_page_url:
            yield response.follow(url=next_page_url, callback=self.parse)



    def parseHomeDepot(self, response):

        items = response.css('.plp-pod')
        for product in items:
            item = HomedepotSpiderItem()

    #get SKU
            productSKU = product.css('.pod-plp__model::text').getall()

    #get rid of all the stuff i dont need
            productSKU = [x.strip(' ') for x in productSKU] #whiteSpace
            productSKU = [x.strip('\n') for x in productSKU]
            productSKU = [x.strip('\t') for x in productSKU]
            productSKU = [x.strip(' Model# ') for x in productSKU] #gets rid of the model name
            productSKU = [x.strip('\xa0') for x in productSKU] #gets rid of the model name



            item['productSKU'] = productSKU

            yield item

问题的说明

这是我一直在抓取数据的程序的一部分。我遗漏了我的代码来抓取其他字段,因为我认为没有必要在这篇文章中添加。当我运行该程序并将数据导出到excel时,我得到了前240个项目(10页)。到电子表格的第241行(第一行被标签占据)。然后从第242行开始,再次重复前241行。然后再次在第482和722行。

Scraper会先输出前240个项目3次

编辑 因此,我在抓取期间查看了日志,结果发现每个页面都被抓取了。最后一页是:

https://www.homedepot.com/b/Appliances/ZLINE-Kitchen-and-Bath/N-5yc1vZbv1wZhsy?experienceName=default&Nao=696&Ns=None>

然后,日志文件显示再次抓取的第一页,即:

https://www.homedepot.com/b/Appliances/ZLINE-Kitchen-and-Bath/N-5yc1vZbv1wZhsy?experienceName=default

我认为是因为 enter image description here

我用来导出到excel的终端命令是:

scrapy crawl homeDepotCrawl -t csv -o - > "(File Location)"

编辑:之所以使用此命令,是因为在导出时,Scrapy会将抓取的数据附加到文件中,因此这会擦除目标文件并再次创建它。

我用来获取所有页面的代码是:

<a class="hd-pagination__link" title="Next" href="/b/Appliances/ZLINE-Kitchen-and-Bath/N-5yc1vZbv1wZhsy?experienceName=default&amp;Nao=24&amp;Ns=None" data-pagenumber="2"></a>

最初,我认为是造成此意外行为的网站,所以在settings.py上,我更改了ROBOTSTXT_OBEY = 0,并添加了一个延迟,但没有任何改变。

所以我想提供以下帮助:

-弄清楚为什么CSV输出仅占用前240个项目(10页)并重复3次

-如何确保抓取前30个蜘蛛后不回到首页

2 个答案:

答案 0 :(得分:1)

您的确是从头开始,chrome开发工具显示到达终点时,“下一个”指向第一组项目。

您可以通过查看当前商品索引的逻辑来检测并避免这种情况:

>>> from urllib.parse import urlparse, parse_qs
>>> url = 'https://www.homedepot.com/b/Appliances/ZLINE-Kitchen-and-Bath/N-5yc1vZbv1wZhsy?experienceName=default&Nao=696&Ns=None'
>>> parsed = urlparse(url)
>>> page_index = int(parse_qs(parsed.query)['Nao'][0])
>>> page_index
696

并编辑您的if next_page_url逻辑,以包含诸如and page_index > last_page_index的逻辑

答案 1 :(得分:1)

我建议做这样的事情。主要区别是我从存储在页面上的json中获取信息,并且通过识别Nao是乘积偏移量对自己进行了分页。代码也短得多:

import requests,json,re
product_skus = set()
headers = {'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36'}
base_url = 'https://www.homedepot.com/b/Appliances/ZLINE-Kitchen-and-Bath/N-5yc1vZbv1wZhsy?experienceName=default&Nao=%s'
for page_num in range(1,1000):
    url = base_url % (page_num*24)
    res = requests.get(url, headers=headers)
    json_data = json.loads(re.search(r'digitalData\.content=(.+);', res.text).group(1))
    prev_len = len(product_skus)
    for product in json_data['product']:
        product_skus.add(product['productInfo']['sku'])
    if len(product_skus) == prev_len: break # this line is optional and can determine when you want to break

此外,它看起来像“家得宝”页面每10页(至少在发送的页面中)重复,这就是为什么看到240个限制的原因。这是我自己浏览的示例:

enter image description here