python scrapy从多个解析函数构建同一项:在循环中调用第二个解析函数

2024-06-30 08:55:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图从许多解析函数中构建一个项,因为我从多个URL获取数据, 我尝试迭代一个字典(我使用2个for循环构建),这就是为什么我使用2个for循环来获取生成URL所需的变量 然后,对于每个变量,我调用传递所需URL的第二个解析函数 这就是我想从主解析调用第二个解析函数的地方

   for r in [1,2]:
      for t in [1,2]:
        dataName = 'lane'+str(r)+"Player"+str(t)+"Name"
        dataHolder = 'lane'+str(r)+"Player"+str(t)
        nameP = item[dataName]
        print('before parse ==> lane = ' + str(r) + "  team = " + str(t))
        urlP = 'https://www.leagueofgraphs.com/summoner/euw/'+nameP+'#championsData-soloqueue'
        yield Request( urlP, callback=self.parsePlayer , meta={'item': item , "player" : dataHolder} )  

我使用这些prints()在输出中查看代码的执行情况 在我的第二个解析函数中也是如此,如下所示

def parsePlayer( self , response ):
  item = response.meta['item']
  player = response.meta['player']
  print('after parse ====> ' + player)
  mmr = response.css('.rank .topRankPercentage::text').extract_first().strip().lower()
  mmrP = player+"Mmr"
  item[mmrP] = mmr
  # yield item after the last iteration

(我知道我没有解释代码中的每一个细节,但我认为不需要看到我的问题,在你看到从这些打印中得到的东西之后就不需要了)

result i get

expected result

此外,出于某种原因,每次我运行spyder时,我都会得到不同的随机打印顺序,这令人困惑,我认为这是关于yield的问题。我希望有人能帮我解决这个问题


Tags: 函数inurlforresponseitemmetaplayer
1条回答
网友
1楼 · 发布于 2024-06-30 08:55:29

Scrapy是异步工作的(在它们的official documentation中解释得很清楚),这就是为什么打印顺序看起来是随机的。 除了顺序之外,预期的输出看起来与您得到的结果完全相同。 如果你能解释为什么订单是相关的,我们也许能更好地回答你的问题

如果您希望生成一个项目,其中包含所有4名玩家的数据,可以使用以下结构:

    def start_requests(self):
        # prepare the urls & players:
        urls_dataHolders = []
        for r in [1, 2]:
            for t in [1, 2]:
                dataName = 'lane' + str(r) + "Player" + str(t) + "Name"
                dataHolder = 'lane' + str(r) + "Player" + str(t)
                urlP = 'https://www.leagueofgraphs.com/summoner/euw/' + dataName\
                       + '#championsData-soloqueue'
                urls_dataHolders.append((urlP, dataHolder))

        # get the first url & dataholder
        url, dataHolder = urls_dataHolders.pop()
        yield Request(url,
                      callback=self.parsePlayer,
                      meta={'urls_dataHolders': urls_dataHolders,
                            'player': dataHolder})

    def parsePlayer(self, response):
        item = response.meta.get('item', {})
        urls_dataHolders = response.meta['urls_dataHolders']
        player = response.meta['player']
        mmr = response.css(
            '.rank .topRankPercentage::text').extract_first().strip().lower()
        mmrP = player + "Mmr"
        item[mmrP] = mmr
        try:
            url, dataHolder = urls_dataHolders.pop()
        except IndexError:
            # list of urls is empty, so we yield the item
            yield item
        else:
            # still urls to go through
            yield Request(url,
                          callback=self.parsePlayer,
                          meta={'urls_dataHolders': urls_dataHolders,
                                'item': item,
                                'player': dataHolder})

相关问题 更多 >