json yeid_请问一下, scrapy 在一个 def 里不能发多个 yield Request 请求么?为什么?...

在 Scrapy 中,一个 def 函数内可以发出多个 yield Request 请求。该示例代码展示了如何从京东搜索结果中获取商品详情,并分别请求电子书价格、原价和京东价以及评论数据。如果遇到请求未按预期执行的情况,可能是其他逻辑问题导致,而不是 yield Request 的限制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这是我写的 spider 文件,下面有我碰到的在一个页面内所需要的值,放在 3 个 json 文件中。。。。。所以我在一个函数下写了三个 yield Request 请求……

import scrapy

from scrapy.http import Request

import re

from jingdong.items import JingdongItem

from jingdong.settings import *

class GoodsSpider(scrapy.Spider):

name = 'goods'

allowed_domains = ['jd.com']

start_urls = ['http://jd.com/']

# https://search.jd.com/Search?keyword=图书&enc=utf-8&wq=图书&page=1

# 搜索的起始页

url = "https://search.jd.com/Search?keyword={KEYWORDS}&enc=utf-8&wq={KEYWORDS}&page={page}"

# 电子价格

Eprice_url = "https://c.3.cn/book?skuId={skuId}&cat={cat}&area=1_72_2799_0&callback=book_jsonp_callback"

# 商品价格

price_url = "https://p.3.cn/prices/mgets?type=1&area=1_72_2799_0&pdtk=&pduid=1771569446&pdpin=&pdbp=0&skuIds=J_{skuId}&ext=11100000&callback=jQuery3021180&_=1547383556702"

price2_url = 'https://c0.3.cn/stock?skuId={skuId}&venderId=1000005720&cat={cat}&area=1_72_2799_0&buyNum=1&extraParam={%22originid%22:%221%22}&ch=1&pduid=1771569446&pdpin=&fqsp=0&callback=getStockCallback'

# 评论

comment_url = "https://sclub.jd.com/comment/productPageComments.action?callback=fetchJSON_comment98vv39228&productId={skuId}&score=0&sortType=5&page=0&pageSize=10&isShadowSku=0&fold=1"

def start_requests(self):

for k in range(1,PAGE_NUM):

yield Request(url=self.url.format(KEYWORDS=KEYWORDS,page=2*k-1),callback=self.page_parse)

def page_parse(self, response):

#每页商品 ID

goodsID = response.xpath('//li/@data-sku').extract()

print(goodsID)

for each in goodsID:

goodsurl = "https://item.jd.com/{}.html".format(each)

yield Request(url=goodsurl,callback=self.get_goods_info)

def get_goods_info(self,response):

item = JingdongItem()

#图书链接

item["link"] = response.url

#图书标题

item["title"] = response.xpath('//div[@class="sku-name"]/text()').extract()[0].strip()

#作者

item["writer"] = response.xpath('//div[@class="p-author"]/a/text()').extract()

#提取商品 ID

skuId = re.compile(r'https:..item.jd.com.(\d+).html').findall(response.url)[0]

item['Id'] = skuId

cat = re.compile(r'pcat:\[(.*?)\],').findall(response.text)

cat = re.sub("\|",",",cat[0]).strip("'")

item['catId'] = cat

print(skuId)

print(cat)

# 打开电子书价格

yield Request(url = self.Eprice_url.format(skuId=skuId, cat=cat),meta={'item':item},callback=self.price_parse)

# 打开原价及京东价

yield Request(url = self.price_url.format(skuId=skuId),meta={'item':item},callback=self.jingdong_price_parse)

# 打开评论 json

yield Request(url = self.comment_url.format(skuId=skuId),meta={'item':item},callback=self.comment_parse)

def price_parse(self,response):

item =response.meta['item']

#电子书价格

item["e_price"] = re.compile('"p":"(.*?)",').findall(response.text)[0]

yield item

def jingdong_price_parse(self,response):

item = response.meta['item']

#京东价

item["n_price"] = re.compile('"op":"(.*?)",').findall(response.text)[0]

print(item["n_price"])

#原价

item["o_price"] = re.compile('"m":"(.*?)",').findall(response.text)[0]

if item["n_price"] == None and item["o_price"]== None:

yield Request(url=self.price2_url.format(skuId=item['id'],cat=item['catId']),meta={'item':item}, callback=self.jingdong_price_parse)

else:

yield item

def comment_parse(self,response):

item = response.meta['item']

#评论数

item["comment"] =re.compile('"content":"(.*?)",').findall(response.text)

yield item

如题目说所,这三个请求

# 打开电子书价格

yield Request(url = self.Eprice_url.format(skuId=skuId, cat=cat),meta={'item':item},callback=self.price_parse)

# 打开原价及京东价

yield Request(url = self.price_url.format(skuId=skuId),meta={'item':item},callback=self.jingdong_price_parse)

# 打开评论 json

yield Request(url = self.comment_url.format(skuId=skuId),meta={'item':item},callback=self.comment_parse)

将会只执行最下面的,另外两个获取不到值。我试过单独写一个爬虫来同相同的匹配规则是可以正常获取到的。所以,百思不得其解啊!!!!!

<think>好的,我需要回答用户关于Scrapy框架中`request.jsonurl`的问题。首先,我要确定用户提到的`jsonurl`是否正确,因为根据我的知识,ScrapyRequest对象并没有这个属性。可能用户是打错了,或者是想了解某个特定情况下的用法。 接下来,我需要回忆Scrapy的官方文档中关于Request对象的属性。标准的属性包括url、method、headers、body等,但没有`jsonurl`。可能用户是指处理JSON数据时的某个方法或参数,比如`response.json()`,但这是在Response对象中,而不是Request。 然后,考虑用户可能的意图。他们可能在尝试解析JSON数据时遇到了问题,或者看到某些代码中使用了类似的属性,导致疑问。需要解释清楚正确的属性和方法,并提供示例帮助理解。 还要检查常见的拼写错误,比如`json_url`或者`json()`方法,但确认这些也不存在。因此,应该指出正确的处理方式,比如在Request中设置正确的URL,并在Response中解析JSON数据。 最后,需要给出示例代码,说明如何正确请求和处理JSON响应,同时提醒用户注意属性和方法的正确使用,避免混淆。还要建议他们查阅官方文档以获取准确信息,并保持回答结构清晰,易于理解。</think>在Scrapy框架中,`request.jsonurl` 并不是一个标准的属性或方法。根据你的描述,可能存在以下两种情况需要澄清: --- ### 🛑 **情况分析:可能存在的误解** 1. **拼写检查** 如果你是指 `request.url`(Request对象的标准属性),这是用来获取请求的URL地址的。例如: ```python def parse(self, response): print(response.request.url) # 输出当前请求的URL ``` 2. **JSON相关操作** 如果目标是处理JSON数据,Scrapy中常用的是 `response.json()` 方法(需在Response对象中使用),例如: ```python def parse(self, response): data = response.json() # 自动解析JSON响应内容 print(data["key"]) ``` --- ### ✅ **正确用法详解** #### 1. 获取请求URL - **属性名**: `request.url` - **作用**: 直接访问请求的完整URL - **示例**: ```python yield scrapy.Request( url="https://example.com/api/data", callback=self.parse_api, meta={"original_url": "https://example.com"} # 可通过meta传递额外信息 ) def parse_api(self, response): print(response.request.url) # 输出: https://example.com/api/data print(response.meta["original_url"]) # 输出: https://example.com ``` #### 2. 处理JSON响应 - **方法**: `response.json()` - **要求**: Response的 `Content-Type` 必须是 `application/json` - **示例**: ```python def parse(self, response): try: json_data = response.json() yield {"data": json_data["results"]} except JSONDecodeError: self.logger.error("非JSON响应") ``` --- ### 🔍 **常见错误场景** 1. **误用属性名** ```python # ❌ 错误写法 print(request.jsonurl) # 会触AttributeError ``` 2. **未检查响应类型** ```python # ❌ 如果响应不是JSON会报错 data = response.json() ``` --- ### 🛠 **最佳实践建议** 1. **调试请求URL** 在爬虫开阶段添加调试输出: ```python def parse(self, response): self.logger.debug(f"当前请求URL: {response.request.url}") ``` 2. **安全处理JSON** 使用异常捕获增强健壮性: ```python def parse(self, response): try: return response.json() except Exception as e: self.logger.warning(f"JSON解析失败: {str(e)}") return {} ``` 3. **API请求专用配置** 对JSON API请求可统一设置Headers: ```python class ApiSpider(scrapy.Spider): def start_requests(self): yield scrapy.Request( url=self.api_url, headers={"Accept": "application/json"}, # 明确要求JSON格式 callback=self.parse_json ) ``` --- 如果问题仍未解决,请提供以下信息以便进一步分析: 1. 完整的代码片段 2.错误的具体场景 3. Scrapy版本 (`scrapy version` 命令输出)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值