Scrapy.Request与requests库请求API的差异及响应格式疑问
问题:Scrapy与Requests请求API的响应差异原因分析
我是Scrapy新手,爬取依赖JavaScript加载内容的网站时,找到了目标API地址https://directory.ntschools.net/api/System/GetAllSchools。直接在浏览器打开该地址返回XML格式,但浏览器网络面板里的响应是JSON。
- 用Scrapy不带请求头请求时,返回XML,调用
json.loads()触发JSONDecode错误;添加Accept: application/json请求头后,成功拿到JSON响应,代码如下:
import scrapy import json import requests class NtseSpider_new(scrapy.Spider): name = 'ntse_new' header = { 'Accept': 'application/json', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.56', } def start_requests(self): yield scrapy.Request('https://directory.ntschools.net/api/System/GetAllSchools',callback=self.parse,headers=self.header) def parse(self,response): data = json.loads(response.body) #returned json response
- 但用Requests库不带请求头请求时,直接得到了JSON响应,代码如下:
import requests import json res = requests.get('https://directory.ntschools.net/api/System/GetAllSchools') js = json.loads(res.content) #returned json response
想请教:两种请求存在哪些差异?requests库请求API时是否有默认响应格式?
问题解答
1. Scrapy与Requests请求的核心差异
核心差异在于默认请求头的不同:
- Scrapy默认的
Accept请求头偏向XML格式,通常为text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,会引导服务器优先返回XML响应;同时它的默认User-Agent是Scrapy/<version> (+https://scrapy.org),服务器可能识别出这是爬虫工具,返回预设的XML内容。 - Requests库默认的
Accept请求头是*/*(表示接受任何格式),默认User-Agent为python-requests/<version> (+https://requests.readthedocs.io),还会自动带上Accept-Encoding等贴近浏览器的请求头字段,服务器的内容协商逻辑会更倾向于返回JSON格式。
2. Requests库的默认响应格式逻辑
Requests本身没有预设“默认响应格式”,它只是被动接收服务器返回的内容。不带请求头也能拿到JSON,是因为它的默认请求头组合刚好符合服务器返回JSON的判定条件。本质是服务器的内容协商机制在起作用:服务器会根据请求中的Accept、User-Agent等字段,判断客户端期望的内容格式,返回对应的响应。
内容的提问来源于stack exchange,提问作者Pranav Anand
相关产品推荐
相关产品推荐

