Scrapy混合物品领域

时间:2018-03-21 10:50:33

标签: python web-scraping scrapy

我正在尝试使用scrapy来搜索TripAdvisor的餐厅评论。单个餐厅的评论在不同的网页上分享(分页)。我抓取评论,然后将结果保存在JSON文件或mongoDB中。

问题在于,当我检查在控制台中刮下的物品时,评论是混合的,例如餐厅A将有其评论和餐厅B的一些评论,餐厅B将缺少这些评论。

我尝试更改设置中的MAX_CONCURRENT_REQUESTS但不影响结果。

这是spider.py代码

class TripAdvisorItemSpider(scrapy.Spider):
name = 'tripadvisor'

custom_settings = {
    'COLLECTION_NAME' : 'tripadvisor'
}


def __init__(self, depth="1", *args, **kwargs):
    super(TripAdvisorItemSpider, self).__init__(*args, **kwargs)
    self.start_urls = get_start_urls()
    self.depth = int(depth)


def start_requests(self):
    for url in self.start_urls:
        yield scrapy.Request(url = url, callback = self.parse, meta = {'item' : Place.Place()})

def parse_review_page(self, response):        
    #On ajoute les reviews de la page actuelle à celle de la page précèdente
    item = response.meta['item']
    item['reviews'] += get_page_reviews(response)

    if(len(self.urls) > 0):
        yield scrapy.Request(url= self.urls.pop(0), callback = self.parse_review_page, meta = {'item' : item})
    else: 
        yield item

def parse(self, response):
    if (self.depth > 1):
        self.urls = create_pagination_urls(response.request.url, self.depth)
    item = response.meta['item']
    item['place'] = response.css("h1::text").extract_first()
    item['content'] = get_content(response)
    item['reviews'] = get_page_reviews(response)
    if(self.depth > 1):
        yield scrapy.Request(url=self.urls.pop(0), callback=self.parse_review_page, meta = {'item' : item})
    else:
        yield item

我遇到了这个问题,它必须与请求对象的生命周期有关,但我无法弄清楚我做错了什么。

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

我找到了答案,

我发现请求,即使我使用MAX_CONCURRENT_REQUESTS = 1也是异步发送的,而不是按照它们被调用的顺序发送!

这导致self.urls在两个分页请求之间被重新定义,替换正确的页面以与另一个餐馆的页面进行迭代。

我通过将类属性self.urls转换为我从一个请求传递给另一个请求的常规变量解决了这个问题。

当天的课程:

  • 请记住,即使在简单的情况下,scrapy请求也会非常异步
  • 处理类属性时要小心