一日一技:Scrapy 如何正确 Post 发送 JSON 数据

举报
未闻Code 发表于 2022/04/08 22:33:12 2022/04/08
【摘要】 在使用 Scrapy 的时候,很多人都知道怎么提交 GET 请求,但却不太清楚怎么提交 POST 请求。

图片

我们知道,HTTP请求的 POST 方式,提交上去的数据有很多种格式。例如JSON/form-data/x-www-form-urlencoded等等。我们在 Postman 的 POST 请求里面,可以看到这些数据格式,如下图所示:

图片

虽然同样都是 POST 方式,但是有些网站只能使用特定的格式才能正常返回数据。我们来看一个例子,现在向网址:http://exercise.kingname.info/ajax_1_postbackend POST 提交一个 JSON 字符串:{“name”:”xx”,”age”:24}可以正常得到返回:

图片

但如果提交的数据格式不是 JSON,而是form-data,那么就会报错,如下图所示:

图片

这也就是为什么在使用 requests 的时候,post 方法的第二个参数有data=和json=的区别,如下图所示:

图片

在使用 Scrapy 的时候,很多人都知道怎么提交 GET 请求,但却不太清楚怎么提交 POST 请求。如果你在网上搜索,那么,你会看到有两种回答:

第一种回答,会建议你使用scrapy.FormRequest。但这个方法提交的数据是form-data格式,如果网站需要接收 JSON 格式的数据,那么提交就会失败。

第二种回答,会建议你使用scrapy.Request(url, method='POST', body=json.dumps(xxx))。这种方式确实可以成功提交 JSON 数据,但写起来比较麻烦。

但如果你看过 Scrapy 的官方文档Requests and Responses[1],你就会知道,实际上 Scrapy 原本就提供了一个专门用来POST 提交 JSON 数据的方式——JsonRequest。它的位置在scrapy.http.JsonRequest。并且使用起来跟 scrapy.Request一样简单:

import scrapy
from scrapy.http import JsonRequest


class ExampleSpider(scrapy.Spider):
    name = 'example'
    allowed_domains = ['xxx.com']
    # start_urls = ['http://xxx.com/']

    def start_requests(self):
        body = {
            'name': 'kingname',
            'age': 28
        }
        url = 'http://exercise.kingname.info/ajax_1_postbackend'
        yield JsonRequest(url, data=body, callback=self.parse)


    def parse(self, response, *args, **kwargs):
        print(response.body.decode())

运行效果如下图所示:

图片

JsonRequest本来就是scrapy.Request的一个子类,所以所有能在scrapy.Request使用的参数,都可以直接在JsonRequest中使用。同时,它额外支持两个参数,分别是data和dumps_kwargs。其中data参数的值就是一个可以被json.dumps序列化的对象,例如字典或者列表。而dumps_kwargs里面的参数,就是 json.dumps支持的那些参数,例如ensure_ascii=False、sort_keys=True等等。

大家遇到问题多看官方文档,少在网上搜索些杂七杂八装逼货的烂博客。官方文档是你最好的朋友。

参考资料

[1] Requests and Responses: https://doc.scrapy.org/en/latest/topics/request-response.html#jsonrequest
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。