正文
【Python】 http客户端库requests & urllib2 以及ip地址处理IPy
小程序:扫一扫查出行
【扫一扫了解最新限行尾号】
复制小程序
【扫一扫了解最新限行尾号】
复制小程序
requests
requests是个HTTPClient库,相比于urllib,urllib2等模块比更加简洁易用
■get请求
作为示例,讲一下关于requests如何发起并处理一个get请求
r = requests.get("http://www.baidu.com") #可以加入timeout参数来设置超时
r是一个Response对象,可以用r查看很多信息
如r.status_code查看本次请求的http返回码
r.headers头部信息(是个类字典对象)
r.url本次请求用的url
r.encoding编码方式
r.text正文
r.content正文
*text和content的区别是text是以unicode的形式存在内存中的,而content是把text用r.encoding编码进行encode之后的产物。所以当返回内容是html文本时,type(text)是unicode而type(content)是str。当返回的是类似于图片这样的东西时,编码可以是base64这种二进制编码,所以如果要下载一张图或一个文件时,应该写入本地文件的也是content而不是text。
再啰嗦一句。。下载的如果是文本文件的话写入方式似乎不带b也行得通,但是如果想下载图片等其他文件就必须是二进制写入了,要不然会打不开的。
r.cookies获得返回内容中的cookie内容,若想在请求中加入cookie的话只要在参数中加上cookies={...}即可
r对象还有一些方法:
r.raise_for_status()#当返回码不是200的时候抛出一个HTTPError异常
另外,get方法还可以把一个字典整合到url中去形成一个带参数的GET请求。比如
par = {'wd':'word'}
r = requests.get("http://www.baidu.com/s",params=par)>>>r.url
u'http://www.baidu.com/s?wd=word'
如果返回的是个json串,那么r还可以用json()方法构造出这个串对应的python字典
r = requests.get("url")#假设返回的json是 {"code":"200","msg":"OK"}res = r.json()
print res.get("code"),res.get("msg")
#得到的就是200 OK
除了params参数之外,get方法还可以有proxies参数以设置代理;headers参数来伪造请求头部(现在很多网站因为防止爬虫等一些原因会检查请求头部,如果不伪造头部的话很可能会出现500状态的返回)
比如headers={'User-Agent':'test'};r = requests.get(url,headers=headers)
加入cookies={一个字典}来增加请求中的cookie信息
■POST
POST请求用post方法,和get类似的设置。
在加上post的数据时注意参数是data不是params了!! ==> r = requests.post(url,data=par)
■请求https地址
请求https地址时,由于涉及到SSL证书的验证等工作,和普通的HTTP请求还不太一样。比如get方法中默认会带上参数verify=True表示请求前要先验证对方的SSL公钥证书。如果确认不用验证可以将此参数置为False,这样就不用验证了。
有时候验证会报错hostname does not match xxxx,这可能是因为你请求的url的域名,其上面的SSL公钥证书还没有被导入当前主机,一个解决办法是将证书导出后存放在某个地方,然后verify参数写指向证书文件的路径。证书导出随各种浏览器、工具不同而不同。比如火狐的话右键页面--查看页面信息--安全--查看证书详细,中可以选择导出。
如果选择了正确的证书之后,请求仍然报错:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed,这个错误可能是由于openssl版本过低。
■上传带中文名的文件
用requests的post方法可以方便地上传文件,一般的做法是这样的:
import requestsdata = {
'other_data': 'value'
}
fi = open('test.jpg','rb')
files = {
'test.jpg': ('test.jpg',fi,'image/jpg')
}url = 'http://127.0.0.1/uploadtest/'
res = requests.post(url, data=data, files=files)
fi.close()
print res.status_code,res.content
可以看到,除了data参数之外添加了files参数。files参数的内容是一个字典,字典中的key可以写file或者其他的什么内容。其对标的是网页表单提交时input标签中name属性的值。一般而言只要保证多个上传文件的键值对中,key没有重复的即可。value是一个tuple,其中各项元素的意义是(filename, file_object, content_type, ...)等,后面还有,不常用就没写。文件名是定义在这里的。如果要上传多个文件,那么就在这个字典中多加几个键值对。需要注意文件对象fi一直到post方法被调用后才能close,否则会报错。
这里面隐藏着一个问题,当上传的文件名是中文名的时候后端可能会获取不到文件的内容,比如用flask做后端时看一下request.files可以看到是个空字典。网上给出了一些解决方法(https://segmentfault.com/q/1010000002633223/a-1020000002657633),比如修改requests中packages/urllib3/fields.py中的一些源代码,尝试了一下确实可以解决。不过修改源码不是很好的解决方法,如果后端也是自己写的话那么可以参考这篇教程中的解决方法三(http://www.mamicode.com/info-detail-1499317.html)。
我的解决办法就是(由于服务器端也是我自己写的),在data中加上filename字段指出中文的,实际的文件名。然后在files中的value那个tuple中的第一项(注意,是{'test.jpg': ('test.jpg', fi)}这个文件名)那个文件名改成file_name或者其他不带中文的名字。在服务端的代码中,首先按照提供的非中文文件名保存下来,然后改名为中文文件名;或者直接按照提供的中文文件名保存,这个取决于后端的规则和写法。比如通过flask搭建的一个服务接受中文名文件上传:
#####服务端代码#####
@app.route('/uploadtest/',methods=['POST'])
def upload_file():
filenames = request.form.get('filename').split(',')
count = 0
for _,storage in request.files.iteritems():
storage.save(os.path.join(BASEDIR,'upload',filenames[count]))
count += 1
# ...#####客户端代码#####
from collections import OrderedDictdata = {
'filename': 'a.txt,b.jpg,c.exe'
}
f1,f2,f3 = open('a.txt','rb'),open('b.jpg','rb'),open('c.exe','rb')
files['a.txt'] = ('f1',f1)
files['b.jpg'] = ('f2',f2)
files['c.exe'] = ('f3',f3)
res = requests.post('http://localhost/uploadtest/',data=data,files=files)
f1.close();f2.close();f3.close()
用了OrderedDict的原因是为了让filename参数得到的文件名列表和上传文件通过顺序一一对应,避免文件名和文件错位。
urllib2
urllib2是比requests更加贴近底层,可以实现更加个性化的HTTPClient?
■基本用法
req = urllib2.Request('...') #用一个url来建立一个Request对象,这个url可以是http协议的也可以是ftp协议的response = urllib2.urlopen(req) #打开这一request对象page = response.read() #response可以像一个文件一样read内容
如果是使用http协议进行通信的话,用户可以通过POST或GET方法来丰富自己的http请求方式,比如自己附上一些表单data,或者添加http的headers信息
① 增加表单data
首先需要一个python字典来抽象化要发送的数据,然后一定要用urllib.urlencode将这个字典处理成urlopen可以识别的东西(好像就是个key=value&key2=value2这样的,跟在get请求的url后面的那种形式)。然后在创建Request对象的时候就有两种方法,分别对应着POST请求和GET请求
par = {'wd':'word'}
processed_par = urllib.urlencode(par) #对字典进行处理,用到的是urllib中的urlencode方法req = urllib2.Request('url',data=processed_par) #写个参数data=处理好的数据这种方式呢对应的是POST请求
req = urllib2.Request(''url'+'?'+processed_par) #直接加上处理好的数据是指GET请求的方式(不要忘了中间的问号!!!urllib2.urlopen(req) #打开Request对象来进行访问
② 增加header信息
header即头部,http头部属于http讯息的一部分,其逻辑形式大致是一个字典,内容包括客户端可接受的内容类型,编码,语言,证书信息,用户所用代理(浏览器的牌子)是什么等等。从应用逻辑上分,header又被分成了general header,request header,response header和entity header四部分
因为urllib2主要是个http客户端库,所以主要关注request header的部分
如以下做法可以为header添加上User-Agent信息(用户的浏览器是什么)
url = 'http://www.xxxxxxxx...'userAgent = 'Mozilla 4.0 xxxxx' #模拟火狐浏览器的信息headers = {'User-Agent':userAgent} #设置header字典data = urllib.urlencode(...) #POST请求的表单数据
req = urllib2.Request(url,data=data,headers=headers)
res = urllib2.urlopen(req) #这就是打开了带有自己定义的头部信息的请求了
■零碎的记录
*关于错误 URLError & HTTPerror
这两个错误是在应用http客户端库时常见的错误。首先,HTTPerror是URLError的一个子类,即发生HTTPError时必然发生URLError
另外,URLError通常是指没有网络连接(没有特定路由到指定服务器),或者服务器不存在的错误。对应的,HTTPError指的是那些服务器指向正确并且连接OK,但是无法完成请求的情况。
URLError对象通常都有reason属性,是个tuple,[0]是错误号,[1]是错误信息,所以在except URLError的时候可以print e.reason来查看具体信息。类似的HTTPError则有一个code属性,记录的是http返回码,如众所周知的404代表找不到文件,401代表需要验证,500代表服务器内部出错等等。
*关于url的解码和编码
有些符号如'{','\'是无法被识别的,需要对其进行编码成%7B,%5C之类的某种我也说不太清到底是什么码的码,可以用urllib.quote(url)对url进行一个编码,同样的urllib.unquote(url)是把编好码的url解码成人看得懂的形式。
IPy
一个小模块。。没地方放了,反正这篇好像都是跟网络沾边就放着把。
本来我想找个能验证ip地址合法性的模块,而找到的这个IPy似乎功能要更加强大一些。IPy下载地址https://github.com/haypo/python-ipy/
●对ip的处理
首先用IPy.IP来建立一个IP对象
ip = IP('x.x.x.x') #在构造IP对象时就已经对ip合法性做出判断,如果不对就报错了。我最开始的需求就这么实现了。。
IP对象有__repr__方法,可以直接被print成字符串。
ip.make_net('子网掩码')返回这个ip所在的网段地址,比如
ip = IP(127.0.0.1)
net = ip.make_net('255.0.0.0')
print net
##输出结果就是 IP('127.0.0.0/8')print ip in net
##还可以直接用 in 语句来判断某个ip在不在一个网段里
●对网段地址的处理
在构造的时候,如果写的是一个网络,那么IP类会自动将其识别成一个网络
net = IP('127.0.0.0/24')
这个net对象时iterable的,可以迭代出这个网段里所有的ip地址,用len(net)自然就可以看到这个网段里一共能有多少ip了
在print net的是时候同样会打印出来这个网络,只是表示一个网络有多种方法,到底取哪一种呢?
可以用net.strNormal(n)这个方法来改变打印出来的格式,比如上面那个net,如果设置了n是0的话只打印出127.0.0.0(网络地址)
n为1的场合 打印出类似于127.0.0.0/24 这种表现形式
n为2的场合 打印出127.0.0.0/255.255.255.0的形式
n为3的场合 打印出127.0.0.0 - 127.0.0.255的形式
【Python】 http客户端库requests & urllib2 以及ip地址处理IPy的更多相关文章- 【网络爬虫入门02】HTTP客户端库Requests的基本原理与基础应用
[网络爬虫入门02]HTTP客户端库Requests的基本原理与基础应用 广东职业技术学院 欧浩源 1.引言 实现网络爬虫的第一步就是要建立网络连接并向服务器或网页等网络资源发起请求.urllib是 ...
- Python中第三方库Requests库的高级用法详解
Python中第三方库Requests库的高级用法详解 虽然Python的标准库中urllib2模块已经包含了平常我们使用的大多数功能,但是它的API使用起来让人实在感觉不好.它已经不适合现在的时代, ...
- JAVA获取客户端请求的当前网络ip地址(附:Nginx反向代理后获取客户端请求的真实IP)
1. JAVA获取客户端请求的当前网络ip地址: /** * 获取客户端请求的当前网络ip * @param request * @return */ public static String get ...
- python Requests库网络爬取IP地址归属地的自动查询
#IP地址查询全代码import requestsurl = "http://m.ip138.com/ip.asp?ip="try: r = requests.get(url + ...
- 【转】Python 第三方 http 库-Requests 学习
原文地址:http://www.itwhy.org/%E8%BD%AF%E4%BB%B6%E5%B7%A5%E7%A8%8B/python/python-%E7%AC%AC%E4%B8%89%E6%9 ...
- Python 第三方 http 库-Requests 学习
Requests 是用Python语言编写,基于 urllib,采用 Apache2 Licensed 开源协议的 HTTP 库.它比 urllib 更加方便,可以节约我们大量的工作,完全满足 HTT ...
- openstack私有云布署实践【19 通过python客户端 创建实例VM指定IP地址】
还有一种创建方式 是使用py开发工具,调用openstackclient的方法进行创建实例 ,好处就是可随意指定我们要的虚拟机IP地址,需求的场景就是,某天我们需要主动分配一个比较熟知的IP用作某个服 ...
- python 跨平台获取网卡信息和本机ip地址
笔者在项目中遇到过获取本机网卡ip的例子,利用python库psutil解决了此问题. def get_netcard(): """获取网卡名称和ip地址 "& ...
- python学习-判断是否是私网IP地址
判断是否是私网IP地址 私网IP地址范围如下: 192.168.0.0-192.168.255.255 172.16.0.0-172.31.255.255 10.0.0.0-10.255.255.25 ...
随机推荐- Android SDK Manager无法显示可供下载的未安装SDK解决方案
FAQ: 问下的 我的ANDROID SDK MANAGER里原来下载了一些SDK,但是我现在想重新下载新的SDK,咋Packages列表没显示呢?该怎么办? Answer: 据说dl-ssl.goo ...
- java三大框架学习总结(1)
企业里并不一定就会用这三种框架,关键是要你能懂得面向对象的原理,以及对服务器客户端请求响应方式的理解,再加上你对缓存的利用,这才能成为真正的高手,框架就好比是一把武器,它最多是能帮你更好的杀敌,而如果 ...
- lintcode:Binary Tree Postorder Traversal 二叉树的后序遍历
题目: 二叉树的后序遍历 给出一棵二叉树,返回其节点值的后序遍历. 样例 给出一棵二叉树 {1,#,2,3}, 1 \ 2 / 3 返回 [3,2,1] 挑战 你能使用非递归实现么? 解题: 递归程序 ...
- spring事务传播机制实例讲解
http://kingj.iteye.com/blog/1680350 spring事务传播机制实例讲解 博客分类: spring java历险 天温习spring的事务处理机制,总结 ...
- DOS批处理命令-@命令
@命令是一个禁止当前语句回显的简单命令. 语法: @[command].[command]是要屏蔽的批处理命令 例如执行包含以下内容的bat文件 echo on @echo ------- @echo ...
- 《think in python》学习-5
think in python -5 think in python -5 条件和递归 求模操作符% 用于整数,可以计算出第一个操作数除以第二个操作数的余数 7%3 #结果是2 求模操作符%有很多用途 ...
- jmeter和loadrunner关于分布式部署测试计划的优缺点
1.都可以实现分布式负载,相对来说loadrunner更强大一些 2.都支持在windows和linux环境的负载生成器,控制台方面,jmeter跨平台,而loadrunner不是 3.loadrun ...
- manjaro安装及设置
因我的笔记本(联想的拯救者)昨晚打开后什么都还没做就被更新系统“抢走”了画面导致按什么都不管用 所以就想起能不能不用win系统,都知道linux比win稳定,so....就找到了manjaro.以下是 ...
- STRANS一:简单的XML转换
心情不好,泥总把表妹微信给冰冰了,心塞... 1.简单的单层结构: <?sap.transform simple?> <tt:transform xmlns:tt="htt ...
- Linker Scripts3--简单的链接脚本命令2-Assigning Values to Symbols
1.前言 本章继续讲述简单脚本命令的后半部分 2.Assigning Values to Symbols 你可以给一个符号(symbol)赋值,它会把这些定义的符号放入全局符号表(symbols ta ...
[网络爬虫入门02]HTTP客户端库Requests的基本原理与基础应用 广东职业技术学院 欧浩源 1.引言 实现网络爬虫的第一步就是要建立网络连接并向服务器或网页等网络资源发起请求.urllib是 ...
Python中第三方库Requests库的高级用法详解 虽然Python的标准库中urllib2模块已经包含了平常我们使用的大多数功能,但是它的API使用起来让人实在感觉不好.它已经不适合现在的时代, ...
1. JAVA获取客户端请求的当前网络ip地址: /** * 获取客户端请求的当前网络ip * @param request * @return */ public static String get ...
#IP地址查询全代码import requestsurl = "http://m.ip138.com/ip.asp?ip="try: r = requests.get(url + ...
原文地址:http://www.itwhy.org/%E8%BD%AF%E4%BB%B6%E5%B7%A5%E7%A8%8B/python/python-%E7%AC%AC%E4%B8%89%E6%9 ...
Requests 是用Python语言编写,基于 urllib,采用 Apache2 Licensed 开源协议的 HTTP 库.它比 urllib 更加方便,可以节约我们大量的工作,完全满足 HTT ...
还有一种创建方式 是使用py开发工具,调用openstackclient的方法进行创建实例 ,好处就是可随意指定我们要的虚拟机IP地址,需求的场景就是,某天我们需要主动分配一个比较熟知的IP用作某个服 ...
笔者在项目中遇到过获取本机网卡ip的例子,利用python库psutil解决了此问题. def get_netcard(): """获取网卡名称和ip地址 "& ...
判断是否是私网IP地址 私网IP地址范围如下: 192.168.0.0-192.168.255.255 172.16.0.0-172.31.255.255 10.0.0.0-10.255.255.25 ...
- Android SDK Manager无法显示可供下载的未安装SDK解决方案
FAQ: 问下的 我的ANDROID SDK MANAGER里原来下载了一些SDK,但是我现在想重新下载新的SDK,咋Packages列表没显示呢?该怎么办? Answer: 据说dl-ssl.goo ...
- java三大框架学习总结(1)
企业里并不一定就会用这三种框架,关键是要你能懂得面向对象的原理,以及对服务器客户端请求响应方式的理解,再加上你对缓存的利用,这才能成为真正的高手,框架就好比是一把武器,它最多是能帮你更好的杀敌,而如果 ...
- lintcode:Binary Tree Postorder Traversal 二叉树的后序遍历
题目: 二叉树的后序遍历 给出一棵二叉树,返回其节点值的后序遍历. 样例 给出一棵二叉树 {1,#,2,3}, 1 \ 2 / 3 返回 [3,2,1] 挑战 你能使用非递归实现么? 解题: 递归程序 ...
- spring事务传播机制实例讲解
http://kingj.iteye.com/blog/1680350 spring事务传播机制实例讲解 博客分类: spring java历险 天温习spring的事务处理机制,总结 ...
- DOS批处理命令-@命令
@命令是一个禁止当前语句回显的简单命令. 语法: @[command].[command]是要屏蔽的批处理命令 例如执行包含以下内容的bat文件 echo on @echo ------- @echo ...
- 《think in python》学习-5
think in python -5 think in python -5 条件和递归 求模操作符% 用于整数,可以计算出第一个操作数除以第二个操作数的余数 7%3 #结果是2 求模操作符%有很多用途 ...
- jmeter和loadrunner关于分布式部署测试计划的优缺点
1.都可以实现分布式负载,相对来说loadrunner更强大一些 2.都支持在windows和linux环境的负载生成器,控制台方面,jmeter跨平台,而loadrunner不是 3.loadrun ...
- manjaro安装及设置
因我的笔记本(联想的拯救者)昨晚打开后什么都还没做就被更新系统“抢走”了画面导致按什么都不管用 所以就想起能不能不用win系统,都知道linux比win稳定,so....就找到了manjaro.以下是 ...
- STRANS一:简单的XML转换
心情不好,泥总把表妹微信给冰冰了,心塞... 1.简单的单层结构: <?sap.transform simple?> <tt:transform xmlns:tt="htt ...
- Linker Scripts3--简单的链接脚本命令2-Assigning Values to Symbols
1.前言 本章继续讲述简单脚本命令的后半部分 2.Assigning Values to Symbols 你可以给一个符号(symbol)赋值,它会把这些定义的符号放入全局符号表(symbols ta ...