请求头中的内容:javascript
request: 最基本的HTTP请求模块,能够用来模拟发送请求。就像在浏览器里输入网址而后回车同样,只须要给库方法传入 URL 以及额外的参数,就能够模拟实现这个过程了 ,同时它还带有处理受权验证( authenticaton )、重定向( redirection)、浏览器 Cookies 以及其余内容。html
urllib.request.urlopen() 为最基本HTTP请求的方法java
import urllib.request response= urllib.request.urlopen('https://www.python.org') print(response.read().decode ('utf-8')) //打印出网页的源代码 print(type(response)) //<class ’ http.client.HTTPResponse ’ >说明该对象类型为HTTPResponse类型。 print(response.status) //200 print(response.getheaders()) // [('Server', 'nginx'), ('Content-Type', 'text/html; charset=utf-8'), ('X-Frame-Options', 'DENY'), ('Via', '1.1 vegur'), ('Via', '1.1 varnish'), ('Content-Length', '48995'), ('Accept-Ranges', 'bytes'), ('Date', 'Mon, 13 May 2019 09:23:37 GMT'), ('Via', '1.1 varnish'), ('Age', '3595'), ('Connection', 'close'), ('X-Served-By', 'cache-iad2139-IAD, cache-tyo19927-TYO'), ('X-Cache', 'HIT, HIT'), ('X-Cache-Hits', '1, 6071'), ('X-Timer', 'S1557739417.434556,VS0,VE0'), ('Vary', 'Cookie'), ('Strict-Transport-Security', 'max-age=63072000; includeSubDomains')] print(response.getheader('Server')) //nginx
HTTPResposne类型的对象,主要包含python
read()、 readinto()、 getheader(name)、getheaders()、 fileno()等方法,以及 msg、 version、status、reason、debuglevel、closed等属性。
若是想给连接传递一些参数,该怎么实现呢?首先看一下urlopen()
函数的 API:nginx
urllib.request.urlopen(url, data=None, timeout=<object object at 0x1102821a0>, *, cafile=None, capath=None, cadefault=False, context=None)
• data
参数
data 参数是可选的。 若是要添加该参数,而且若是它是字节流编码格式的内容,即 bytes 类型, 则须要经过 bytes()方法转化。 另外,若是传递了这个参数,则它的请求方式就再也不是 GET方式,而是POST方式。json
import urllib data = bytes(urllib.parse.urlencode({'word':'hello'}), encoding='utf8') //经过utf8的格式将字典进行字节流的编码, response= urllib.request.urlopen('http://httpbin.org/post', data=data) //将编码后的字节流数据传输到指定URL print(response.read().decode('utf-8'))//这里存在一个bug,要进行指定方式解码。
Result:浏览器
{ "args": {}, "data": "", "files": {}, "form": { "word": "hello" }, "headers": { "Accept-Encoding": "identity", "Content-Length": "10", "Content-Type": "application/x-www-form-urlencoded", "Host": "httpbin.org", "User-Agent": "Python-urllib/3.6" }, "json": null, "origin": "171.81.189.140, 171.81.189.140", "url": "https://httpbin.org/post" }
• timeout参数
timeout参数用于设置超时时间,单位为秒,意思就是若是请求超出了设置的这个时间,尚未获得响应,就会抛出异常。若是不指定该参数,就会使用全局默认时间。它支持HTTP,HTTPS,FTP请求。缓存
import socket import urllib try: response = urllib.request.urlopen('http://httpbin.org/get', timeout=0.1) //若是时间超过0.1S不响应就报错。 except urllib.error.URLError as e: if isinstance(e.reason,socket.timeout): print("TIME OUT!")
• 其余参数
除了data参数和timeout参数外,还有context参数,它必须是 ssl.SSLContext类型,用来指定SSL 设置。此外,cafile和 capath这两个参数分别指定 CA证书和它的路径,这个在请求 HTTPS连接时会有用。
cadefault参数如今已经弃用了,其默认值为 False。服务器
import urllib.request request = urllib.request.Request("https://python.org") response = urllib .request.urlopen(request) print(response.read().decode ('utf-8'))
依然是用 urlopen()方法来发送这个请求,只不过该方法的参数再也不是 URL, 而是一个 Request 类型的对象。经过构造这个数据结构,一方面咱们能够将请求独立成一个对象,另 一方面可更加丰富和灵活地配置参数 。数据结构
class urllib. request. Request (url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)
添加请求头最经常使用的用法就是经过修改 User-Agent 来假装浏览器,默认的 User-Agent 是Python-urllib,咱们能够经过修改它来假装浏览器 。 好比要假装火狐浏览器,你能够把它设置为 :Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:66.0) Gecko/20100101 Firefox/66.0
第六个参数 method是一个字符串 ,用来指示请求使用的方法,好比 GET、 POST和 PUT等
from urllib import parse,request url = 'http://httpbin.org/post' headers = { 'User-Agent':'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)', 'Host' :'httpbin.org' } dict={ 'name':'Gremey' } data= bytes(parse.urlencode(dict), encoding='utf-8') #req = request.Request(url=url, data=data, headers=headers, method='POST') //上面是直接写好headers传递参数传递给对象,下面是单独的经过对象的方法传递 req=request.Request(url=url, data=data, method='POST') req.add_header('User-Agent','Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)') response = request.urlopen(req) print(response.read().decode('utf-8'))
在上面的过程当中,咱们虽然能够构造请求,可是对于一些更高级的操做(好比 Cookies处理 、 代理设置等),该如何处理?
就须要更强大的工具 Handler 登场了。简而言之,咱们能够把它理解为各类处理器,有专门处理登陆验证的,有处理 Cookies 的,有处理代理设置的。利用它们,咱们几乎能够作到 HTTP请求中全部的事。urllib .request
模块里的 BaseHandler
类,它是全部其余 Handler 的父类,它提 供了最基本的方法,例如 default_open()、 protocol_request()
等。
接下来,就有各类 Handler 子类继承这个 BaseHandler类,举例以下 。
另外一个比较重要的类就是 OpenerDirector,咱们能够称为 Opener。 咱们以前用过 urlopen()这个方法,实际上它就是urllib为咱们提供的一个Opener。那么,为何要引人Opener 呢?由于须要实现更高级的功能。以前使用的 Request 和 urlopen() 至关于类库为你封装好了极其经常使用的请求方法,利用它们能够完成基本的请求,可是如今不同了,咱们须要实现更高级的功能,因此须要深刻一层进行配置,使用更底层的实例来完成操做,因此这里就用到了Opener。Opener可使用 open()方法,返回的类型和urlopen()一模一样。 那么,它和 Handler 有什么关 系呢?简而言之,就是利用 Handler来构建 Opener。