我正在写一个令人毛骨悚然的爬虫,以便从亚马逊那里获取衬衫信息。搜寻器从亚马逊页面开始进行搜索,例如搜索“有趣的衬衫”,然后收集所有结果项容器。然后,它分析每个结果项,以收集衬衫上的数据。
我使用ScraperAPI和Scrapy-user-agents躲避亚马逊。我的蜘蛛的代码是:
class AmazonSpiderSpider(scrapy.Spider):
name = 'amazon_spider'
page_number = 2
keyword_file = open("keywords.txt", "r+")
all_key_words = keyword_file.readlines()
keyword_file.close()
all_links = []
keyword_list = []
for keyword in all_key_words:
keyword_list.append(keyword)
formatted_keyword = keyword.replace('\n', '')
formatted_keyword = formatted_keyword.strip()
formatted_keyword = formatted_keyword.replace(' ', '+')
all_links.append("http://api.scraperapi.com/?api_key=mykeyd&url=https://www.amazon.com/s?k=" + formatted_keyword + "&ref=nb_sb_noss_2")
start_urls = all_links
def parse(self, response):
print("========== starting parse ===========")
all_containers = response.css(".s-result-item")
for shirts in all_containers:
next_page = shirts.css('.a-link-normal::attr(href)').extract_first()
if next_page is not None:
if "https://www.amazon.com" not in next_page:
next_page = "https://www.amazon.com" + next_page
yield scrapy.Request('http://api.scraperapi.com/?api_key=mykey&url=' + next_page, callback=self.parse_dir_contents)
second_page = response.css('li.a-last a::attr(href)').get()
if second_page is not None and AmazonSpiderSpider.page_number < 3:
AmazonSpiderSpider.page_number += 1
yield response.follow(second_page, callback=self.parse)
def parse_dir_contents(self, response):
items = ScrapeAmazonItem()
print("============= parsing page ==============")
temp = response.css('#productTitle::text').extract()
product_name = ''.join(temp)
product_name = product_name.replace('\n', '')
product_name = product_name.strip()
temp = response.css('#priceblock_ourprice::text').extract()
product_price = ''.join(temp)
product_price = product_price.replace('\n', '')
product_price = product_price.strip()
temp = response.css('#SalesRank::text').extract()
product_score = ''.join(temp)
product_score = product_score.strip()
product_score = re.sub(r'\D', '', product_score)
product_ASIN = re.search(r'(?<=/)B[A-Z0-9]{9}', response.url)
product_ASIN = product_ASIN.group(0)
items['product_ASIN'] = product_ASIN
items['product_name'] = product_name
items['product_price'] = product_price
items['product_score'] = product_score
yield items
爬行看起来像这样:
https://i.stack.imgur.com/UbVUt.png
我返回200,所以我知道我从网页上获取数据,但是有时它不会进入parse_dir_contents,或者它只获取了几件衬衫上的信息,然后转到下一个关键字而没有分页之后。
使用两个关键字:文件中的第一个关键字(keywords.txt)已加载,可能找到1-3件衬衫,然后移至下一个关键字。然后,第二个关键字完全成功,找到所有衬衫并进行分页。在具有5个以上关键字的关键字文件中,将跳过前2-3个关键字,然后加载下一个关键字,仅找到2-3个衬衫,然后再移至下一个单词,这再次完全成功。在包含10个以上关键字的文件中,我的行为非常零散。
我不知道为什么会这样吗?有人可以解释吗?
答案 0 :(得分:0)
首先,从您刚才所说的情况来看,我想您是否已经忽略了robots.txt
。
有时,响应中返回的html代码与您查看产品时看到的代码不同。我真的不知道您的情况到底是怎么回事,但是您可以检查蜘蛛实际上正在“阅读”什么。
scrapy shell 'yourURL'
之后
view(response)
您可以在其中签出Spider真正看到的代码,看看请求是否成功。
有时请求不会成功(也许亚马逊正在将您重定向到验证码等)。
您可以在抓取时检查响应(请检查下面的代码,我是从内存中读取的)
import request
#inside your parse method
r = request.get("url")
print(r.content)
如果我没记错的话,您可以从scrapy本身获取URL(类似于response.url
。
答案 1 :(得分:0)
尝试在您的草率请求中使用dont_filter=True
。我遇到了同样的问题,似乎这名爬虫爬虫正在忽略某些URL,因为它认为这些URL是重复的。
dont_filter=True
这可确保scrapy不会使用其dupefilter过滤任何URL。