From:https://www.jb51.net/article/146769.htm

使用 requests 发送 post 请求

先来看看使用requests来发送post请求是多少好用,发送请求
Requests 简便的 API 意味着所有 HTTP 请求类型都是显而易见的。
例如,你可以这样发送一个 HTTP POST 请求:

>>>r = requests.post('http://httpbin.org/post', data = {'key':'value'})

使用data可以传递字典作为参数,同时也可以传递元祖

>>>payload = (('key1', 'value1'), ('key1', 'value2'))
>>>r = requests.post('http://httpbin.org/post', data=payload)
>>>print(r.text)
{..."form": {"key1": ["value1","value2"]},...
}

传递 json 是这样

>>>import json>>>url = 'https://api.github.com/some/endpoint'
>>>payload = {'some': 'data'}>>>r = requests.post(url, data=json.dumps(payload))

2.4.2 版的新加功能:

>>>url = 'https://api.github.com/some/endpoint'
>>>payload = {'some': 'data'}>>>r = requests.post(url, json=payload)

也就是说,你不需要对参数做什么变化,只需要关注使用data=还是json=,其余的requests都已经帮你做好了。

使用scrapy发送post请求

通过源码可知scrapy默认发送的get请求,当我们需要发送携带参数的请求或登录时,是需要post、请求的,以下面为例

from scrapy.spider import CrawlSpider
from scrapy.selector import Selector
import scrapy
import json
class LaGou(CrawlSpider):name = 'myspider'def start_requests(self):yield scrapy.FormRequest(url='https://www.******.com/jobs/positionAjax.json?city=%E5%B9%BF%E5%B7%9E&needAddtionalResult=false',formdata={'first': 'true',#这里不能给bool类型的True,requests模块中可以'pn': '1',#这里不能给int类型的1,requests模块中可以'kd': 'python'},  # 这里的formdata相当于requ模块中的data,key和value只能是键值对形式callback=self.parse)def parse(self, response):datas=json.loads(response.body.decode())['content']['positionResult']['result']for data in datas:print(data['companyFullName'] + str(data['positionId']))

官方推荐的 Using FormRequest to send data via HTTP POST

return [FormRequest(url="http://www.example.com/post/action",formdata={'name': 'John Doe', 'age': '27'},callback=self.after_post)]

这里使用的是FormRequest,并使用formdata传递参数,看到这里也是一个字典。

但是,超级坑的一点来了,今天折腾了一下午,使用这种方法发送请求,怎么发都会出问题,返回的数据一直都不是我想要的

return scrapy.FormRequest(url, formdata=(payload))

在网上找了很久,最终找到一种方法,使用scrapy.Request发送请求,就可以正常的获取数据。

return scrapy.Request(url, body=json.dumps(payload), method='POST', headers={'Content-Type': 'application/json'},)

参考:Send Post Request in Scrapy

my_data = {'field1': 'value1', 'field2': 'value2'}
request = scrapy.Request( url, method='POST', body=json.dumps(my_data), headers={'Content-Type':'application/json'} )

FormRequest 与 Request 区别

在文档中,几乎看不到差别,

The FormRequest class adds a new argument to the constructor. The remaining arguments are the same as for the Request class and are not documented here.
Parameters: formdata (dict or iterable of tuples) – is a dictionary (or iterable of (key, value) tuples) containing HTML Form data which will be url-encoded and assigned to the body of the request.

说FormRequest新增加了一个参数formdata,接受包含表单数据的字典或者可迭代的元组,并将其转化为请求的body。并且FormRequest是继承Request的

class FormRequest(Request):def __init__(self, *args, **kwargs):formdata = kwargs.pop('formdata', None)if formdata and kwargs.get('method') is None:kwargs['method'] = 'POST'super(FormRequest, self).__init__(*args, **kwargs)if formdata:items = formdata.items() if isinstance(formdata, dict) else formdataquerystr = _urlencode(items, self.encoding)if self.method == 'POST':self.headers.setdefault(b'Content-Type', b'application/x-www-form-urlencoded')self._set_body(querystr)else:self._set_url(self.url + ('&' if '?' in self.url else '?') + querystr)###def _urlencode(seq, enc):values = [(to_bytes(k, enc), to_bytes(v, enc))for k, vs in seqfor v in (vs if is_listlike(vs) else [vs])]return urlencode(values, doseq=1)

最终我们传递的{‘key': ‘value', ‘k': ‘v'}会被转化为'key=value&k=v' 并且默认的method是POST,再来看看Request

class Request(object_ref):def __init__(self, url, callback=None, method='GET', headers=None, body=None,cookies=None, meta=None, encoding='utf-8', priority=0,dont_filter=False, errback=None, flags=None):self._encoding = encoding # this one has to be set firstself.method = str(method).upper()

默认的方法是GET,其实并不影响。仍然可以发送post请求。这让我想起来requests中的request用法,这是定义请求的基础方法。

def request(method, url, **kwargs):"""Constructs and sends a :class:`Request <Request>`.:param method: method for the new :class:`Request` object.:param url: URL for the new :class:`Request` object.:param params: (optional) Dictionary or bytes to be sent in the query string for the :class:`Request`.:param data: (optional) Dictionary or list of tuples ``[(key, value)]`` (will be form-encoded), bytes, or file-like object to send in the body of the :class:`Request`.:param json: (optional) json data to send in the body of the :class:`Request`.:param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`.:param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`.:param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload.``file-tuple`` can be a 2-tuple ``('filename', fileobj)``, 3-tuple ``('filename', fileobj, 'content_type')``or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content-type'`` is a stringdefining the content type of the given file and ``custom_headers`` a dict-like object containing additional headersto add for the file.:param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth.:param timeout: (optional) How many seconds to wait for the server to send databefore giving up, as a float, or a :ref:`(connect timeout, readtimeout) <timeouts>` tuple.:type timeout: float or tuple:param allow_redirects: (optional) Boolean. Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to ``True``.:type allow_redirects: bool:param proxies: (optional) Dictionary mapping protocol to the URL of the proxy.:param verify: (optional) Either a boolean, in which case it controls whether we verifythe server's TLS certificate, or a string, in which case it must be a pathto a CA bundle to use. Defaults to ``True``.:param stream: (optional) if ``False``, the response content will be immediately downloaded.:param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair.:return: :class:`Response <Response>` object:rtype: requests.ResponseUsage::>>> import requests>>> req = requests.request('GET', 'http://httpbin.org/get')<Response [200]>"""# By using the 'with' statement we are sure the session is closed, thus we# avoid leaving sockets open which can trigger a ResourceWarning in some# cases, and look like a memory leak in others.with sessions.Session() as session:return session.request(method=method, url=url, **kwargs)

Python 使用 Scrapy 发送 post 请求的坑相关推荐

  1. python使用scrapy_python使用scrapy发送post请求的坑

    标签: 使用 requests 发送 post 请求 先来看看使用requests来发送post请求是多少好用,发送请求 Requests 简便的 API 意味着所有 HTTP 请求类型都是显而易见的 ...

  2. python requests是什么_如何基于Python + requests实现发送HTTP请求

    这篇文章主要介绍了如何基于Python + requests实现发送HTTP请求,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一.在接口自动化测试 ...

  3. python写页面发送post请求_Python模拟浏览器向CSDN发送post请求的方法,POST

    目录 1.发送get请求的方法 import requests import json def GET(url): #get请求 req = requests.get(url) #输出状态码 prin ...

  4. 安装python爬虫scrapy踩过的那些坑和编程外的思考

    '转载地址:http://www.cnblogs.com/rwxwsblog/p/4557123.html' 这些天应朋友的要求抓取某个论坛帖子的信息,网上搜索了一下开源的爬虫资料,看了许多对于开源爬 ...

  5. python使用urllib发送post请求_python使用urllib2提交http post请求的方法

    Python模拟新浪微博登录 看到一篇Python模拟新浪微博登录的文章,想熟悉一下其中实现方式,并且顺便掌握python相关知识点. 代码 下面的代码是来自上面这篇文章,并稍作修改添加了一些注释. ...

  6. 使用 python requests 模块发送 http 请求及接收响应

    内容概要 如何构建GET 与 POST request 请求消息 对 request 的header , query string, message body 定制化 http header参数 co ...

  7. python使用request发送post请求_python之使用request模块发送post和get请求

    import requests import json #发送get请求并得到结果 # url = 'http://api.nnzhp.cn/api/user/stu_info?stu_name=小黑 ...

  8. Python 使用requests发送POST请求

    一个http请求包括三个部分,为别为请求行,请求报头,消息主体,类似以下这样: 请求行  请求报头  消息主体 HTTP协议规定post提交的数据必须放在消息主体中,但是协议并没有规定必须使用什么编码 ...

  9. Python 使用requests发送POST请求总结

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/junli_chen/article/details/53670887 一个http请求包括三个部分, ...

最新文章

  1. ICRA 2021| SKD:基于显着性估计的点云关键点检测
  2. CentOS软/硬RAID安装方法
  3. 小强升职记梗概_《小强升职记》读后感
  4. 【转知乎】人工智能会是泡沫吗?
  5. websocket在web项目中的使用
  6. 【Android进阶学习】Http编程之HttpClient
  7. 【BZOJ2049】【codevs1839】洞穴探测,LCT练习
  8. 锁到底是一种怎样的存在?
  9. Android的手机震动
  10. python123用户登录的三次机会_用户登录三次机会(PYTHON)
  11. Python-模块导入-63
  12. Thingworx入门学习
  13. 英特尔vPro博锐技术激活
  14. Codeforces 645B Mischievous Mess Makers【逆序数】
  15. FFMpeg 4.1 音频检测
  16. 《淘宝网开店 拍摄 修图 设计 装修 实战150招》一一1.8 侧光拍摄增强轮廓感
  17. 如何判断两个链表是否相交并求出相交点
  18. Google AIY 套件将亮相香港!人工智能新一轮风潮袭来!
  19. 力扣算法题(11)动态规划
  20. Cesium中用到的图形技术——Computing the horizon occlusion point

热门文章

  1. 【重版】朴素贝叶斯与拣鱼的故事
  2. 解读 | 滴滴主题研究计划:机器学习专题+
  3. 【LeetCode】4月3日打卡-Day19-字符串转整数
  4. [poj3261]Milk Patterns
  5. 9-18 学习如何使用Python包的管理
  6. GC之七--gc日志分析工具
  7. union intersect minus
  8. teamlab与redmine试用对比报告
  9. 我想知道怎么求N的N次方
  10. 【剑指offer】面试题15:二进制中1的个数(Java)