Python 刮印最后输出三次,而不是三次

Python 刮印最后输出三次,而不是三次,python,python-3.x,web-scraping,scrapy,Python,Python 3.x,Web Scraping,Scrapy,我已经用scrapy编写了一个脚本来解析网站上的一些内容。要从该站点访问数据的相关部分,我需要在有效负载中使用一些ID 我正在一个接一个地使用有效负载中的这三个ID,如24842、19902和20154。但是,我试图检查有效负载是否根据我使用的id进行了更新,但我注意到有效负载使用了最后一个id,如20154中的三次 更清楚地说,我希望得到如下输出: {'language': 'en', 'region': 'ww', 'networks': 'Internet', '$top': '20',

我已经用scrapy编写了一个脚本来解析网站上的一些内容。要从该站点访问数据的相关部分,我需要在有效负载中使用一些ID

我正在一个接一个地使用有效负载中的这三个ID,如
24842
19902
20154
。但是,我试图检查有效负载是否根据我使用的id进行了更新,但我注意到有效负载使用了最后一个id,如
20154
中的三次

更清楚地说,我希望得到如下输出:

{'language': 'en', 'region': 'ww', 'networks': 'Internet', '$top': '20', 'productNodePath': '/24842/'}
{'language': 'en', 'region': 'ww', 'networks': 'Internet', '$top': '20', 'productNodePath': '/19902/'}
{'language': 'en', 'region': 'ww', 'networks': 'Internet', '$top': '20', 'productNodePath': '/20154/'}
我得到的是:

{'language': 'en', 'region': 'ww', 'networks': 'Internet', '$top': '20', 'productNodePath': '/20154/'}
{'language': 'en', 'region': 'ww', 'networks': 'Internet', '$top': '20', 'productNodePath': '/20154/'}
{'language': 'en', 'region': 'ww', 'networks': 'Internet', '$top': '20', 'productNodePath': '/20154/'}
我试过:

import scrapy
from urllib.parse import urlencode
from scrapy.crawler import CrawlerProcess

class SiemensSpider(scrapy.Spider):
    name = 'siemens'

    start_link = "https://support.industry.siemens.com/webbackend/api/ProductSupport/ProductSearch?"

    payload = {
        'language': 'en',
        'region': 'ww',
        'networks': 'Internet',
        '$top': '20'
    }

    def start_requests(self):
        for item_id in ['24842','19902','20154']:
            self.payload['productNodePath'] = f"/{item_id}/" #should be updated here
            first_req = f'{self.start_link}{urlencode(self.payload)}'
            yield scrapy.Request(first_req,callback=self.parse)
        
    def parse(self,response):
        print(self.payload)

if __name__ == "__main__":
    c = CrawlerProcess({
        'USER_AGENT': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36',
        'LOG_LEVEL':'ERROR'
    })
    c.crawl(SiemensSpider)
    c.start()

如何实现第一次输出?

在这种情况下,您必须使用
deepcopy
与请求中的
meta
数据相结合

您正在获取spider的一个属性,并且只覆盖其中一个值,因此您将获得问题中提到的重复数据

工作示例:

import scrapy
from urllib.parse import urlencode
from scrapy.crawler import CrawlerProcess
from copy import deepcopy


class SiemensSpider(scrapy.Spider):
    name = 'siemens'

    start_link = "https://support.industry.siemens.com/webbackend/api/ProductSupport/ProductSearch?"

    payload = {
        'language': 'en',
        'region': 'ww',
        'networks': 'Internet',
        '$top': '20'
    }

    def start_requests(self):
        for item_id in ['24842', '19902', '20154']:
            data = deepcopy(self.payload)
            data['productNodePath'] = f"/{item_id}/"  # should be updated here
            first_req = f'{self.start_link}{urlencode(data)}'
            yield scrapy.Request(first_req, callback=self.parse, meta={'payload': data})

    def parse(self, response):
        payload = response.meta.get('payload')
        print(payload)


if __name__ == "__main__":
    c = CrawlerProcess({
        'USER_AGENT': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36',
        'LOG_LEVEL': 'ERROR'
    })
    c.crawl(SiemensSpider)
    c.start()

在这种情况下,您必须在请求中结合使用
deepcopy
meta
数据

您正在获取spider的一个属性,并且只覆盖其中一个值,因此您将获得问题中提到的重复数据

工作示例:

import scrapy
from urllib.parse import urlencode
from scrapy.crawler import CrawlerProcess
from copy import deepcopy


class SiemensSpider(scrapy.Spider):
    name = 'siemens'

    start_link = "https://support.industry.siemens.com/webbackend/api/ProductSupport/ProductSearch?"

    payload = {
        'language': 'en',
        'region': 'ww',
        'networks': 'Internet',
        '$top': '20'
    }

    def start_requests(self):
        for item_id in ['24842', '19902', '20154']:
            data = deepcopy(self.payload)
            data['productNodePath'] = f"/{item_id}/"  # should be updated here
            first_req = f'{self.start_link}{urlencode(data)}'
            yield scrapy.Request(first_req, callback=self.parse, meta={'payload': data})

    def parse(self, response):
        payload = response.meta.get('payload')
        print(payload)


if __name__ == "__main__":
    c = CrawlerProcess({
        'USER_AGENT': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36',
        'LOG_LEVEL': 'ERROR'
    })
    c.crawl(SiemensSpider)
    c.start()