Python2.X/Python3.X中urllib库区别讲解


Posted in Python onDecember 19, 2017

本文介绍urllib库在不同版本的Python中的变动,并以Python3.X讲解urllib库的相关用法。

urllib库对照速查表

Python2.X Python3.X
urllib urllib.request, urllib.error, urllib.parse
urllib2 urllib.request, urllib.error
urllib2.urlopen urllib.request.urlopen
urllib.urlencode urllib.parse.urlencode
urllib.quote urllib.request.quote
urllib2.Request urllib.request.Request
urlparse urllib.parse
urllib.urlretrieve urllib.request.urlretrieve
urllib2.URLError urllib.error.URLError
cookielib.CookieJar http.CookieJar

urllib库是用于操作URL,爬取页面的python第三方库,同样的库还有requests、httplib2。

在Python2.X中,分urllib和urllib2,但在Python3.X中,都统一合并到urllib中。通过上表可以看到其中常见的变动,依据该变动可快速写出相应版本的python程序。

相对来说,Python3.X对中文的支持比Python2.X友好,所以该博客接下来通过Python3.X来介绍urllib库的一些常见用法。

发送请求

import urllib.request
r = urllib.request.urlopen(http://www.python.org/)

首先导入urllib.request模块,使用urlopen()对参数中的URL发送请求,返回一个http.client.HTTPResponse对象。

在urlopen()中,使用timeout字段,可设定相应的秒数时间之后停止等待响应。除此之外,还可使用r.info()、r.getcode()、r.geturl()获取相应的当前环境信息、状态码、当前网页URL。

读取响应内容

import urllib.request
url = "http://www.python.org/"
with urllib.request.urlopen(url) as r:
r.read()

使用r.read()读取响应内容到内存,该内容为网页的源代码(可用相应的浏览器“查看网页源代码”功能看到),并可对返回的字符串进行相应解码decode()。

传递URL参数

import urllib.request
import urllib.parse
params = urllib.parse.urlencode({'q': 'urllib', 'check_keywords': 'yes', 'area': 'default'})
url = "https://docs.python.org/3/search.html?{}".format(params)
r = urllib.request.urlopen(url)

以字符串字典的形式,通过urlencode()编码,为URL的查询字符串传递数据,

编码后的params为字符串,字典每项键值对以'&'连接:'q=urllib&check_keywords=yes&area=default'

构建后的URL:https://docs.python.org/3/search.html?q=urllib&check_keywords=yes&area=default

当然,urlopen()支持直接构建的URL,简单的get请求可以不通过urlencode()编码,手动构建后直接请求。上述方法使代码模块化,更优雅。

传递中文参数

import urllib.request
searchword = urllib.request.quote(input("请输入要查询的关键字:"))
url = "https://cn.bing.com/images/async?q={}&first=0&mmasync=1".format(searchword)
r = urllib.request.urlopen(url)

该URL是利用bing图片接口,查询关键字q的图片。如果直接将中文传入URL中请求,会导致编码错误。我们需要使用quote(),对该中文关键字进行URL编码,相应的可以使用unquote()进行解码。

定制请求头

import urllib.request
url = 'https://docs.python.org/3/library/urllib.request.html'
headers = {
  'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36',
  'Referer': 'https://docs.python.org/3/library/urllib.html'
}
req = urllib.request.Request(url, headers=headers)
r = urllib.request.urlopen(req)

有时爬取一些网页时,会出现403错误(Forbidden),即禁止访问。这是因为网站服务器对访问者的Headers属性进行身份验证,例如:通过urllib库发送的请求,默认以”Python-urllib/X.Y”作为User-Agent,其中X为Python的主版本号,Y为副版本号。所以,我们需要通过urllib.request.Request()构建Request对象,传入字典形式的Headers属性,模拟浏览器。

相应的Headers信息,可通过浏览器的开发者调试工具,”检查“功能的”Network“标签查看相应的网页得到,或使用抓包分析软件Fiddler、Wireshark。

除上述方法外,还可以使用urllib.request.build_opener()或req.add_header()定制请求头,详见官方样例。

在Python2.X中,urllib模块和urllib2模块通常一起使用,因为urllib.urlencode()可以对URL参数进行编码,而urllib2.Request()可以构建Request对象,定制请求头,然后统一使用urllib2.urlopen()发送请求。

传递POST请求

import urllib.request
import urllib.parse
url = 'https://passport.cnblogs.com/user/signin?'
post = {
  'username': 'xxx',
  'password': 'xxxx'
}
postdata = urllib.parse.urlencode(post).encode('utf-8')
req = urllib.request.Request(url, postdata)
r = urllib.request.urlopen(req)

我们在进行注册、登录等操作时,会通过POST表单传递信息。

这时,我们需要分析页面结构,构建表单数据post,使用urlencode()进行编码处理,返回字符串,再指定'utf-8'的编码格式,这是因为POSTdata只能是bytes或着file object。最后通过Request()对象传递postdata,使用urlopen()发送请求。

下载远程数据到本地

import urllib.request
url = "https://www.python.org/static/img/python-logo.png"
urllib.request.urlretrieve(url, "python-logo.png")

爬取图片、视频等远程数据时,可使用urlretrieve()下载到本地。

第一个参数为要下载的url,第二个参数为下载后的存放路径。

该样例下载python官网logo到当前目录下,返回元组(filename, headers)。

设置代理IP

import urllib.request
url = "https://www.cnblogs.com/"
proxy_ip = "180.106.16.132:8118"
proxy = urllib.request.ProxyHandler({'http': proxy_ip})
opener = urllib.request.build_opener(proxy, urllib.request.HTTPHandler)
urllib.request.install_opener(opener)
r = urllib.request.urlopen(url)

有时频繁的爬取一个网页,会被网站服务器屏蔽IP。这时,可通过上述方法设置代理IP。

首先,通过网上代理IP的网站找一个可以用的IP,构建ProxyHandler()对象,将'http'和代理IP以字典形式作为参数传入,设置代理服务器信息。再构建opener对象,将proxy和HTTPHandler类传入。通过installl_opener()将opener设置成全局,当用urlopen()发送请求时,会使用之前设置的信息来发送相应的请求。

异常处理

import urllib.request
import urllib.error
url = "http://www.balabalabala.org"
try:
  r = urllib.request.urlopen(url)
except urllib.error.URLError as e:
  if hasattr(e, 'code'):
    print(e.code)
  if hasattr(e, 'reason'):
    print(e.reason)

可以使用URLError类,处理一些URL相关异常。导入urllib.error,捕获URLError异常后,因为只有发生HTTPError异常(URLError子类)时,才会有异常状态码e.code,所以需要判断异常是否有属性code。

Cookie的使用

import urllib.request
import http.cookiejar
url = "http://www.balabalabala.org/"
cjar = http.cookiejar.CookieJar()
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cjar))
urllib.request.install_opener(opener)
r = urllib.request.urlopen(url)

通过无状态协议HTTP访问网页时,Cookie维持会话间的状态。例如:有些网站需要登录操作,第一次可通过提交POST表单来登录,当爬取该网站下的其它站点时,可以使用Cookie来保持登录状态,而不用每次都通过提交表单来登录。

首先,构建CookieJar()对象cjar,再使用HTTPCookieProcessor()处理器,处理cjar,并通过build_opener()构建opener对象,设置成全局,通过urlopen()发送请求。

Python 相关文章推荐
浅谈numpy数组的几种排序方式
Dec 15 Python
Python定义一个跨越多行的字符串的多种方法小结
Jul 19 Python
python scipy求解非线性方程的方法(fsolve/root)
Nov 12 Python
浅谈python3.x pool.map()方法的实质
Jan 16 Python
python time.sleep()是睡眠线程还是进程
Jul 09 Python
解决python多行注释引发缩进错误的问题
Aug 23 Python
TensorFlow打印输出tensor的值
Apr 19 Python
Python使用configparser读取ini配置文件
May 25 Python
浅谈Python中的生成器和迭代器
Jun 19 Python
使用Tensorflow-GPU禁用GPU设置(CPU与GPU速度对比)
Jun 30 Python
Python编写单元测试代码实例
Sep 10 Python
解决jupyter notebook图片显示模糊和保存清晰图片的操作
Apr 24 Python
Python实现采用进度条实时显示处理进度的方法
Dec 19 #Python
Python实现矩阵加法和乘法的方法分析
Dec 19 #Python
分析python切片原理和方法
Dec 19 #Python
python实现redis三种cas事务操作
Dec 19 #Python
Python2/3中urllib库的一些常见用法
Dec 19 #Python
Python与人工神经网络:使用神经网络识别手写图像介绍
Dec 19 #Python
Python random模块用法解析及简单示例
Dec 18 #Python
You might like
用php实现像JSP,ASP里Application那样的全局变量
2007/01/12 PHP
PHP中大括号'{}'用法实例总结
2017/02/08 PHP
PHP中的使用curl发送请求(GET请求和POST请求)
2017/02/08 PHP
URI、URL和URN之间的区别与联系
2006/12/20 Javascript
使用Mootools动态添加Css样式表代码,兼容各浏览器
2011/12/12 Javascript
弹出最简单的模式化遮罩层的js代码
2013/12/04 Javascript
JavaScript数组深拷贝和浅拷贝的两种方法
2014/04/16 Javascript
JavaScript实现找质数代码分享
2015/03/24 Javascript
Javascript实现div的toggle效果实例分析
2015/06/09 Javascript
angular.js分页代码的实例
2016/07/27 Javascript
js数组与字符串常用方法总结
2017/01/13 Javascript
Bootstrap 下拉多选框插件Bootstrap Multiselect
2017/01/22 Javascript
JS简单获得节点元素的方法示例
2018/02/10 Javascript
在微信小程序中渲染HTML内容的方法示例
2018/09/28 Javascript
使用vue 国际化i18n 实现多实现语言切换功能
2018/10/11 Javascript
微信小程序实现页面下拉刷新和上拉加载功能详解
2018/12/03 Javascript
Vue如何基于es6导入外部js文件
2020/05/15 Javascript
[57:59]EG vs Secret 2018国际邀请赛淘汰赛BO3 第一场 8.22
2018/08/23 DOTA
Python 不同对象比较大小示例探讨
2014/08/21 Python
Pythont特殊语法filter,map,reduce,apply使用方法
2016/02/27 Python
python中reduce()函数的使用方法示例
2017/09/29 Python
Python 读取图片文件为矩阵和保存矩阵为图片的方法
2018/04/27 Python
浅析Python 实现一个自动化翻译和替换的工具
2019/04/14 Python
python Pandas库基础分析之时间序列的处理详解
2019/07/13 Python
PyTorch里面的torch.nn.Parameter()详解
2020/01/03 Python
Python ini文件常用操作方法解析
2020/04/26 Python
Python如何将将模块分割成多个文件
2020/08/04 Python
python openssl模块安装及用法
2020/12/06 Python
CSS3实现王者荣耀匹配人员加载页面的方法
2019/04/16 HTML / CSS
美国著名手表网站:Timepiece
2017/11/15 全球购物
俄罗斯Sportmarket体育在线商店:用于旅游和户外活动
2019/11/12 全球购物
优秀团支部事迹材料
2014/02/08 职场文书
奥巴马获胜演讲稿
2014/05/15 职场文书
整改报告格式
2014/11/06 职场文书
CSS几步实现赛博朋克2077风格视觉效果
2021/06/16 HTML / CSS
四十九个javascript小知识实用技巧
2021/11/20 Javascript