Python中操作HTTP请求的urllib模块详解
urllib 是 Python 标准库中用于网络请求的库。该库有四个模块,分别是urllib.request,urllib.error,urllib.parse,urllib.robotparser。
1 发起请求
模拟浏览器发起一个 HTTP 请求,我们需要用到 urllib.request 模块。urllib.request 的作用不仅仅是发起请求, 还能获取请求返回结果。发起请求,单靠 urlopen() 方法就可以叱咤风云。我们先看下 urlopen() 的 API
urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
- 第一个参数 String 类型的地址或者
data是 bytes 类型的内容,可通过 bytes()函数转为化字节流。它也是可选参数。使用 data 参数,请求方式变成以 POST 方式提交表单。使用标准格式是application/x-www-form-urlencodedtimeout参数是用于设置请求超时时间。单位是秒。cafile和capath代表 CA 证书和 CA 证书的路径。如果使用HTTPS则需要用到。context参数必须是ssl.SSLContext类型,用来指定SSL设置cadefault参数已经被弃用,可以不用管了。- 该方法也可以单独传入
urllib.request.Request对象 - 该函数返回结果是一个
http.client.HTTPResponse对象。
1.1 简单抓取网页
我们使用 urllib.request.urlopen() 去请求百度贴吧,并获取到它页面的源代码。
import urllib.request url = "http://tieba.baidu.com"
response = urllib.request.urlopen(url)
html = response.read() # 获取到页面的源代码
print(html.decode('utf-8')) # 转化为 utf-8 编码
1.2 设置请求超时
有些请求可能因为网络原因无法得到响应。因此,我们可以手动设置超时时间。当请求超时,我们可以采取进一步措施,例如选择直接丢弃该请求或者再请求一次。
import urllib.request url = "http://tieba.baidu.com"
response = urllib.request.urlopen(url, timeout=1)
print(response.read().decode('utf-8'))
1.3 使用 data 参数提交数据
在请求某些网页时需要携带一些数据,我们就需要使用到 data 参数。
import urilib.parse
import urllib.request url = "http://127.0.0.1:8000/book"
params = {
'name':'浮生六记',
'author':'沈复'
} data = bytes(urllib.parse.urlencode(params), encoding='utf8')
response = urllib.request.urlopen(url, data=data)
print(response.read().decode('utf-8'))
params 需要被转码成字节流。而 params 是一个字典。我们需要使用 urllib.parse.urlencode() 将字典转化为字符串。再使用 bytes() 转为字节流。最后使用 urlopen() 发起请求,请求是模拟用 POST 方式提交表单数据。
1.4 使用 Request
由上我们知道利用 urlopen() 方法可以发起简单的请求。但这几个简单的参数并不足以构建一个完整的请求,如果请求中需要加入headers(请求头)、指定请求方式等信息,我们就可以利用更强大的Request类来构建一个请求。
按照国际惯例,先看下 Request 的构造方法:
urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)
url 参数是请求链接,这个是必传参数,其他的都是可选参数。data 参数跟 urlopen() 中的 data 参数用法相同。headers 参数是指定发起的 HTTP 请求的头部信息。headers 是一个字典。它除了在 Request 中添加,还可以通过调用 Reques t实例的 add_header() 方法来添加请求头。origin_req_host 参数指的是请求方的 host 名称或者 IP 地址。unverifiable 参数表示这个请求是否是无法验证的,默认值是False。意思就是说用户没有足够权限来选择接收这个请求的结果。例如我们请求一个HTML文档中的图片,但是我们没有自动抓取图像的权限,我们就要将 unverifiable 的值设置成 True。method 参数指的是发起的 HTTP 请求的方式,有 GET、POST、DELETE、PUT等
1.4.1 简单使用 Request
使用 Request 伪装成浏览器发起 HTTP 请求。如果不设置 headers 中的 User-Agent,默认的User-Agent是Python-urllib/3.5。可能一些网站会将该请求拦截,所以需要伪装成浏览器发起请求。我使用的 User-Agent 是 Chrome 浏览器。
import urllib.request url = "http://tieba.baidu.com/"
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'
}
request = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen(request)
print(response.read().decode('utf-8'))
1.4.2 Request 高级用法
如果我们需要在请求中添加代理、处理请求的 Cookies,我们需要用到Handler和OpenerDirector。
1) Handler
Handler 的中文意思是处理者、处理器。 Handler 能处理请求(HTTP、HTTPS、FTP等)中的各种事情。它的具体实现是这个类 urllib.request.BaseHandler。它是所有的 Handler 的基类,其提供了最基本的Handler的方法,例如default_open()、protocol_request()等。
继承 BaseHandler 有很多个,我就列举几个比较常见的类:
ProxyHandler:为请求设置代理HTTPCookieProcessor:处理 HTTP 请求中的 CookiesHTTPDefaultErrorHandler:处理 HTTP 响应错误。HTTPRedirectHandler:处理 HTTP 重定向。HTTPPasswordMgr:用于管理密码,它维护了用户名密码的表。HTTPBasicAuthHandler:用于登录认证,一般和HTTPPasswordMgr结合使用。
2) OpenerDirector
对于 OpenerDirector,我们可以称之为 Opener。我们之前用过 urlopen() 这个方法,实际上它就是 urllib 为我们提供的一个Opener。那 Opener 和 Handler 又有什么关系?opener 对象是由 build_opener(handler) 方法来创建出来 。我们需要创建自定义的 opener,就需要使用 install_opener(opener)方法。值得注意的是,install_opener 实例化会得到一个全局的 OpenerDirector 对象。
1.5 使用代理
我们已经了解了 opener 和 handler,接下来我们就通过示例来深入学习。第一个例子是为 HTTP 请求设置代理
有些网站做了浏览频率限制。如果我们请求该网站频率过高。该网站会被封 IP,禁止我们的访问。所以我们需要使用代理来突破这“枷锁”。
import urllib.request url = "http://tieba.baidu.com/"
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'
} proxy_handler = urllib.request.ProxyHandler({
'http': 'web-proxy.oa.com:8080',
'https': 'web-proxy.oa.com:8080'
})
opener = urllib.request.build_opener(proxy_handler)
urllib.request.install_opener(opener) request = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen(request)
print(response.read().decode('utf-8'))
1.6 认证登录
有些网站需要携带账号和密码进行登录之后才能继续浏览网页。碰到这样的网站,我们需要用到认证登录。我们首先需要使用 HTTPPasswordMgrWithDefaultRealm() 实例化一个账号密码管理对象;然后使用 add_password() 函数添加账号和密码;接着使用 HTTPBasicAuthHandler() 得到 hander;再使用 build_opener() 获取 opener 对象;最后使用 opener 的 open() 函数发起请求。
第二个例子是携带账号和密码请求登录百度贴吧,代码如下:
import urllib.request url = "http://tieba.baidu.com/"
user = 'user'
password = 'password'
pwdmgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
pwdmgr.add_password(None,url ,user ,password) auth_handler = urllib.request.HTTPBasicAuthHandler(pwdmgr)
opener = urllib.request.build_opener(auth_handler)
response = opener.open(url)
print(response.read().decode('utf-8'))
1.7 Cookies设置
如果请求的页面每次需要身份验证,我们可以使用 Cookies 来自动登录,免去重复登录验证的操作。获取 Cookies 需要使用 http.cookiejar.CookieJar() 实例化一个 Cookies 对象。再用 urllib.request.HTTPCookieProcessor 构建出 handler 对象。最后使用 opener 的 open() 函数即可。
第三个例子是获取请求百度贴吧的 Cookies 并保存到文件中,代码如下:
import http.cookiejar
import urllib.request url = "http://tieba.baidu.com/"
fileName = 'cookie.txt' cookie = http.cookiejar.CookieJar()
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
response = opener.open(url) f = open(fileName,'a')
for item in cookie:
f.write(item.name+" = "+item.value+'\n')
f.close()
1.8 HTTPResponse
从上面的例子可知, 使用 urllib.request.urlopen() 或者 opener.open(url) 返回结果是一个 http.client.HTTPResponse 对象。它具有 msg、version、status、reason、debuglevel、closed等属性以及read()、readinto()、getheader(name)、getheaders()、fileno()等函数。
2 错误解析
发起请求难免会出现各种异常,我们需要对异常进行处理,这样会使得程序比较人性化。
异常处理主要用到两个类,urllib.error.URLError和urllib.error.HTTPError。
URLError
URLError 是 urllib.error 异常类的基类, 可以捕获由urllib.request 产生的异常。
它具有一个属性reason,即返回错误的原因。
捕获 URL 异常的示例代码:
import urllib.request
import urllib.error url = "http://www.google.com"
try:
response = request.urlopen(url)
except error.URLError as e:
print(e.reason)
HTTPErrorHTTPError 是 UEKRrror 的子类,专门处理 HTTP 和 HTTPS 请求的错误。它具有三个属性。1)code:HTTP 请求返回的状态码。1)renson:与父类用法一样,表示返回错误的原因。1)headers`:HTTP 请求返回的响应头信息。
获取 HTTP 异常的示例代码, 输出了错误状态码、错误原因、服务器响应头
import urllib.request
import urllib.error url = "http://www.google.com"
try:
response = request.urlopen(url)
except error.HTTPError as e:
print('code: ' + e.code + '\n')
print('reason: ' + e.reason + '\n')
print('headers: ' + e.headers + '\n')
Python中操作HTTP请求的urllib模块详解的更多相关文章
- Python中生成器和yield语句的用法详解
Python中生成器和yield语句的用法详解 在开始课程之前,我要求学生们填写一份调查表,这个调查表反映了它们对Python中一些概念的理解情况.一些话题("if/else控制流" ...
- python中利用队列asyncio.Queue进行通讯详解
python中利用队列asyncio.Queue进行通讯详解 本文主要给大家介绍了关于python用队列asyncio.Queue通讯的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细 ...
- python接口自动化(九)--python中字典和json的区别(详解)
简介 这篇文章的由来是由于上一篇发送post请求的接口时候,参数传字典(dict)和json的缘故,因为python中,json和dict非常类似,都是key-value的形式,为啥还要这么传参,在群 ...
- Python urllib模块详解
在Python 2中,有urllib和urllib2两个库来实现请求的发送.而在Python 3中,已经不存在urllib2这个库了,统一为urllib,其官方文档链接为:https://docs.p ...
- python中的列表(list) 切片详解
1.切片: 通过指定下标的方式来获得某一个数据元素,或者通过指定下标范围来获得一组序列的元素,这种访问序列的方式叫做切片. 访问某一个数据元素的的语法如下: sequence[index] ...
- python标准库介绍——2 os.path模块详解
== os.path 模块 == ``os.path`` 模块包含了各种处理长文件名(路径名)的函数. 先导入 (import) ``os`` 模块, 然后就可以以 ``os.path`` 访问该模块 ...
- Python中strip()、lstrip()、rstrip()用法详解
Python中有三个去除头尾字符.空白符的函数,它们依次为: strip: 用来去除头尾字符.空白符(包括\n.\r.\t.' ',即:换行.回车.制表符.空格)lstrip:用来去除开头字符.空白符 ...
- Python中str.format()字典及list传入详解
- Python中操作mysql的pymysql模块详解
Python中操作mysql的pymysql模块详解 前言 pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb几乎相同.但目前pymysql支持python3.x而后者不支持 ...
随机推荐
- WebStorm 最新版本激活方式
WebStorm 最新版本激活方式:今天下载最新版本的WebStorm,发现原来的通过license server激活的方式,网上的已经失效. 找到一种最新的激活码,今天试了下,是有效的.记录下. 注 ...
- day 51 随机验证码, 验证登陆 ,以及 装饰器在函数中的应用
前端很好的session 的例子 (随机验证码登陆) https://github.com/Endless-Clould/qianduan 参考: 验证码登录 https://www.cnblogs. ...
- php 类继承
%token T_EXTENDS "extends (T_EXTENDS)" unticked_class_declaration_statement: class_entry_t ...
- 使用BeanUitls提高对象拷贝效率
首先来创建两个bean 注:一定要有set/get方法,成员变量必须要同名 public class User1 { String name; String password; String phon ...
- POJ 1118
#include<iostream> #include<set> #include<stdio.h> #include<math.h> #include ...
- document文档对象
document 文挡对象 - JavaScript脚本语言描述———————————————————————注:页面上元素name属性和JavaScript引用的名称必须一致包括大小写否则会提示你一 ...
- django框架--cookie/session
目录 一.http协议无状态问题 二.会话跟踪技术--cookie 1.对cookie的理解 2.cookie的使用接口 3.cookie的属性 4.使用cookie的问题 三.会话跟踪技术--ses ...
- 数据输入——生成你需要的echart图(世界地图,气泡图)
上一篇文章介绍了:堆积柱状图.扇形图.嵌套环形图,现在来介绍一下:世界地图和气泡图 1.世界地图 http://echarts.baidu.com/examples/editor.html?c=map ...
- 计算机上面常用的计算单位 & 个人计算机架构与接口设备
不多说,直接上干货! 计算机上面常用的计算单位 容量单位 速度单位 此网络常使用的单位为 Mbps 是 Mbits per second,亦即是每秒多少 Mbit. 个人计算机架构与接口设备 整个 ...
- thread 带参数
在 .NET Framework 2.0 版中,要实现线程调用带参数的方法有两种办法. 第一种:使用ParameterizedThreadStart. 调用 System.Threading.Thre ...