Scrapy 如何使用yield函数从多个页面中提取数据

Scrapy 如何使用yield函数从多个页面中提取数据,scrapy,scrapy-splash,Scrapy,Scrapy Splash,我正试图从亚马逊印度网站上搜集数据。在以下情况下,我无法使用yield()方法收集响应并解析元素: 1) 我必须从产品页面转到评论页面 2) 我必须从一个复习页面转到另一个复习页面 代码流: 1) customerReviewData()调用getCustomerRatingsAndComments(响应) 2) GetCustomerRatings和Comments(响应) 查找审阅页面的URL,并使用getCrrFromReviewPage(request)作为回调方法调用收益请求方法,

我正试图从亚马逊印度网站上搜集数据。在以下情况下,我无法使用yield()方法收集响应并解析元素: 1) 我必须从产品页面转到评论页面 2) 我必须从一个复习页面转到另一个复习页面

代码流:

1) customerReviewData()调用getCustomerRatingsAndComments(响应)

2) GetCustomerRatings和Comments(响应) 查找审阅页面的URL,并使用getCrrFromReviewPage(request)作为回调方法调用收益请求方法,使用此审阅页面的URL

3) getCrrFromReviewPage()获取firstreview页面的新响应,并从firstreview页面(已加载页面)中删除所有元素,并将其添加到customerReviewDataList[]

4) 获取下一页的URL(如果存在),并递归调用getCrrFromReviewPage()方法,并从下一页抓取元素,直到对所有审阅页进行抓取

5) 所有评论都将添加到customerReviewDataList[]

我尝试过使用yield()修改参数,还查阅了有关yield()和请求/响应的详细文档


感谢您的帮助。提前感谢。

您应该完成Scrapy教程。这一部分应该对你特别有帮助

这是代码的简化版本:

def data_request_iterator():
屈服请求('https://example.org')
类MySpider(Spider):
name='myspider'
起始URL=['https://example.com']
def解析(自我,响应):
屈服{
“title”:response.css('title::text').get(),
“数据”:数据请求迭代器(),
}
相反,它应该是这样的:

class MySpider(Spider):
name='myspider'
起始URL=['https://example.com']
def解析(自我,响应):
项目={
“title”:response.css('title::text').get(),
}
屈服请求('https://example.org“,meta={'item':item},callback=self.parse_data)
def解析_数据(自身、响应):
item=response.meta['item']
#TODO:根据需要使用第二个响应中的数据扩展项。
收益项目

我没有深入研究您的代码,但有两件事值得注意:(1)不要使用全局变量;使用
meta
从一个
请求
到它的回调进行通信(2)
callback=getCrrFromReviewPage())
不做你想做的事;使用parens意味着调用
getCrrFromReviewPage
,并使用其返回值作为
callable
,而不是
callback=getCrrFromReviewPage)
意味着使用实际方法作为
回调
。您还应该得到这样的信息,即
getCrrFromReviewPage
缺少
响应
参数您的Spider类在哪里?你已经完成了这个枯燥的教程了吗?谢谢@MatthewLDaniel:我得到了你的第1点,关于第2点,我试着运行以下
callback=getCrrFromReviewPage()
callback=getCrrFromReviewPage
,还使用了
yield response.follow(url,self.callbackMethod)
但是我的回调方法没有被调用/执行。另外,我们不必在回调方法中传递响应作为参数,scrapy隐式地获取传递的URL的响应,该URL可以在回调方法中使用。感谢@Gallaecio,我在教程中,上面代码中存在的蜘蛛类。感谢@Gallaecio,当parse_data()从内部递归调用,列表多次生成,列表中有新旧注释,是否有任何方法,我可以将所有注释存储在列表中,并在末尾仅调用一次生成项如果您在完成教程后仍然不确定,请打开关于第二个问题的新Stackoverflow问题。
# -*- coding: utf-8 -*-
import scrapy
import logging

customerReviewDataList = []
customerReviewData = {}

#Get product name in <H1>
def getProductTitleH1(response):
    titleH1 =  response.xpath('normalize-space(//*[@id="productTitle"]/text())').extract()
    return titleH1

def getCustomerRatingsAndComments(response):
    #Fetches the relative url
    reviewRelativePageUrl = response.css('#reviews-medley-footer a::attr(href)').extract()[0]
    if reviewRelativePageUrl:
        #get absolute URL
        reviewPageAbsoluteUrl = response.urljoin(reviewRelativePageUrl)
        yield Request(url = reviewPageAbsoluteUrl, callback = getCrrFromReviewPage())
        self.log("yield request complete")

    return len(customerReviewDataList)

def getCrrFromReviewPage():

    userReviewsAndRatings = response.xpath('//div[@id="cm_cr-review_list"]/div[@data-hook="review"]')


    for userReviewAndRating in userReviewsAndRatings:
        customerReviewData[reviewTitle] = response.css('#cm_cr-review_list .review-title span ::text').extract()
        customerReviewData[reviewDescription] = response.css('#cm_cr-review_list .review-text span::text').extract()
        customerReviewDataList.append(customerReviewData) 

    reviewNextPageRelativeUrl = response.css('#cm_cr-pagination_bar .a-pagination .a-last a::attr(href)')[0].extract()

    if reviewNextPageRelativeUrl:
        reviewNextPageAbsoluteUrl = response.urljoin(reviewNextPageRelativeUrl)
        yield Request(url = reviewNextPageAbsoluteUrl, callback = getCrrFromReviewPage())


class UsAmazonSpider(scrapy.Spider):
    name = 'Test_Crawler'
    allowed_domains = ['amazon.in']
    start_urls = ['https://www.amazon.in/Philips-Trimmer-Cordless-Corded-QT4011/dp/B00JJIDBIC/ref=sr_1_3?keywords=philips&qid=1554266853&s=gateway&sr=8-3']

    def parse(self, response):
        titleH1 = getProductTitleH1(response),
        customerReviewData = getCustomerRatingsAndComments(response)

        yield{
        'Title_H1' : titleH1,
        'customer_Review_Data' : customerReviewData
        }


{'Title_H1': (['Philips Beard Trimmer Cordless and Corded for Men QT4011/15'],), 'customer_Review_Data': <generator object getCustomerRatingsAndComments at 0x048AC630>}
{'customerReviewTitle': ['Difficult to find a charger adapter'],'customerReviewComment': ['I already have a phillips trimmer which was only cordless. ], 'customerReviewTitle': ['Good Product'],'customerReviewComment': ['Solves my need perfectly HK']}]}