python - 刮印最后输出三遍而不是三遍
问题描述
我已经使用scrapy 编写了一个脚本来解析网站上的一些内容。要从该站点访问数据的相关部分,我需要在有效负载中使用一些 id。
我正在一个接一个地尝试在有效负载中使用这三个 id,如24842
,19902
和20154
. 但是,我正在尝试根据我使用的 id 检查有效负载是否已更新,但我注意到有效负载正在使用最后一个 id,如20154
3 次。
为了更清楚,我想得到如下输出:
{'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
请求中的数据使用。
您正在获取蜘蛛的属性并仅覆盖其中一个值,因此您会得到问题中提到的重复数据。
工作示例:
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()
推荐阅读
- python - Python dict.update vs 在开始时完全初始化
- javascript - 在松弛模态视图中显示错误
- java - Java 版本混淆
- html - 非梯形rotate3d视频问题
- javascript - 为什么我的角色权限代码不起作用?(discord.js)
- docker - Lumen Nginx 资产路径问题
- php - 如何使用 $_SESSION 显示消息
- r - 如何根据第二个可能的值范围合并两个数据帧,但保留第一个的值?
- sql - sql查询查找租赁天数大于等于10天的客户
- composer-php - 在 Composer 中创建项目时如何使用全局 composer.json?