为什么Scrapy会跳过某些URL,而不是其他URL?

时间:2019-09-02 16:49:02

标签: python proxy scrapy amazon middleware

我正在写一个令人毛骨悚然的爬虫,以便从亚马逊那里获取衬衫信息。搜寻器从亚马逊页面开始进行搜索,例如搜索“有趣的衬衫”,然后收集所有结果项容器。然后,它分析每个结果项,以收集衬衫上的数据。

我使用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个以上关键字的文件中,我的行为非常零散。

我不知道为什么会这样吗?有人可以解释吗?

2 个答案:

答案 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。

相关问题