python request请求
2016-03-22 15:57
567 查看
有时候我们需要用脚本模仿浏览器向服务器发送请求,这个时候首先需要打开浏览器进入调试功能,然后找到发送请求时浏览器所发送的数据,包括请求的header和数据部分。如下图所示:
这是请求的header
这是请求的content部分
要模拟浏览器发送请求很简单,就是将上面的信息全都封装成json的数据格式,然后发送给服务器就好了。
下面是用python request实现的。需要注意的是,服务器需要进行csrftoken验证。为了让同一个对象能够跨请求保持某些参数,同一个Session实例发出的所有请求之间cookies是相同的,所以我们需要跨请求来保持cookies
下面是代码:
在向别的url发送请求的过程中,我发现了有时候我们发送的数据不是form data而是multipart/form-data,和form data比起来这个数据格式就看起来比较复杂:
multipart/form-data主要由三部分组成:
1 HTTP Header。需要添加头"Content-Type: multipart/form-data; boundary=%s",这个boundary就是分隔符,见第二条。
2 分隔符boundary。分隔符是一串和正文内容不冲突的字符串,用以分割多个参数。一般都是N个减号+随机字符串,比如"----------当前时间"。
正文需要加header:Content-Disposition: form-data; name="%s",%s为需要传递的变量名。
Content-Type: 指定正文MIME类型,默认是纯文本text/plain,未知类型可以填application/octet-stream。
3 数据。要注意的是数据的编码,文档上说"7BIT encoding",ISO-8859-1即可。
我试了好几种方法,后来发现,对发送的数据按照上面的那种格式进行处理以后然后按照刚才的方法发送比较有效。
代码如下:
这是请求的header
这是请求的content部分
要模拟浏览器发送请求很简单,就是将上面的信息全都封装成json的数据格式,然后发送给服务器就好了。
下面是用python request实现的。需要注意的是,服务器需要进行csrftoken验证。为了让同一个对象能够跨请求保持某些参数,同一个Session实例发出的所有请求之间cookies是相同的,所以我们需要跨请求来保持cookies
下面是代码:
import requests login_url = 'http://example.com' client=requests.session() client.get(login_url) csrf_token=client.cookies['csrftoken'] hed={'X-CSRFToken':csrf_token,'Refer':'http://example.com','User-Agent':'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36','Content-Type':'application/x-www-form-urlencoded'} udata={'csrfmiddlewaretoken':csrf_token,'username':'111','password':'123456','this_is_the_login_form':1,'next':'/admin/'} r=client.post(login_url,data=udata,headers=hed)
在向别的url发送请求的过程中,我发现了有时候我们发送的数据不是form data而是multipart/form-data,和form data比起来这个数据格式就看起来比较复杂:
multipart/form-data主要由三部分组成:
1 HTTP Header。需要添加头"Content-Type: multipart/form-data; boundary=%s",这个boundary就是分隔符,见第二条。
2 分隔符boundary。分隔符是一串和正文内容不冲突的字符串,用以分割多个参数。一般都是N个减号+随机字符串,比如"----------当前时间"。
正文需要加header:Content-Disposition: form-data; name="%s",%s为需要传递的变量名。
Content-Type: 指定正文MIME类型,默认是纯文本text/plain,未知类型可以填application/octet-stream。
3 数据。要注意的是数据的编码,文档上说"7BIT encoding",ISO-8859-1即可。
我试了好几种方法,后来发现,对发送的数据按照上面的那种格式进行处理以后然后按照刚才的方法发送比较有效。
代码如下:
import requests import time import string def _encode_multipart(params_dict): boundary = '----%s' % hex(int(time.time() * 10000000)) data = [] for k, v in params_dict.items(): data.append('--%s' % boundary) if hasattr(v, 'read'): filename = getattr(v, 'name', '') content = v.read() decoded_content = content.decode('ISO-8859-1') data.append('Content-Disposition: form-data; name="%s"; filename="hidden"' % k) data.append('Content-Type: application/octet-stream\r\n') data.append(decoded_content) else: data.append('Content-Disposition: form-data; name="%s"\r\n' % k) data.append(v if isinstance(v, str) else v.decode('utf-8')) data.append('--%s--\r\n' % boundary) return '\r\n'.join(data), boundary usradd_url='http://example.com' client.get(usradd_url) csrf_token1=client.cookies['csrftoken'] username='test'+str(i) print username fdata={'csrfmiddlewaretoken':csrf_token,'username':username,'password1':'123456','password2':'123456','_save':'Save'} rfdata,boundary=_encode_multipart(fdata) nbdry='multipart/form-data;boundary='+boundary hed1={'X-CSRFToken':csrf_token,'Refer':'http://example.com','User-Agent':'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36','Content-Type':nbdry} re=client.post(usradd_url,data=rfdata.encode('ISO-8859-1'),headers=hed1) print re.status_code
相关文章推荐
- [LeetCode]题解(python):128-Longest Consecutive Sequence
- LintCode:快乐数
- python中文乱码
- Python多线程返回执行结果
- python 利用sklearn自带的模块 快速简单实现文章的 tfidf向量空间的表示
- [LeetCode]题解(python):127-Word Ladder
- python调试技巧
- [LeetCode]题解(python):126-Word Ladder II
- Python debug——TypeError: unhashable type(list/set/dict)
- Python—I/O多路复用
- Python traceback
- python基础01
- 随机sample文件Python程序
- python进程和线程学习
- [LeetCode]题解(python):125-Valid Palindrome
- Python 时间 日期常见操作
- [LeetCode]题解(python):124-Binary Tree Maximum Path Sum
- 构造Python中的常量类
- python--基础学习(三)字符串单引号、双引号、三引号
- 【翻译】Leapmotion-python开发官方文档(10)