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次
编辑 因此,我在抓取期间查看了日志,结果发现每个页面都被抓取了。最后一页是:
然后,日志文件显示再次抓取的第一页,即:
我用来导出到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&Nao=24&Ns=None" data-pagenumber="2"></a>
最初,我认为是造成此意外行为的网站,所以在settings.py上,我更改了ROBOTSTXT_OBEY = 0
,并添加了一个延迟,但没有任何改变。
所以我想提供以下帮助:
-弄清楚为什么CSV输出仅占用前240个项目(10页)并重复3次
-如何确保抓取前30个蜘蛛后不回到首页
答案 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个限制的原因。这是我自己浏览的示例: