前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >初识urllib

初识urllib

作者头像
py3study
发布2020-01-20 11:28:10
6100
发布2020-01-20 11:28:10
举报
文章被收录于专栏:python3python3

使用urllib

request:  是最基本的 HTTP 请求模块,可以用来模拟发送请求,只需要给库方法传入URL以及额外的参数,就可以模拟实现这个过程了。

error:  异常处理模块,如果出现请求错误, 可以捕获这些异常,然后进行重试或其它操作以保证程序不会意外终止。

parse:  工具模块,提供了许多 URL 处理方法,比如拆分、解析,合并等。

robotparser:  主要是用来识别网站的robots.txt 文件,然后判断哪些网站可以爬,哪些网站不可以爬,用得较少。

发送请求

使用urllib的request模块,可以实现请求的发送并得到响应

具体用法:

urlopen()

urllib.request 模块提供了最基本的构造 HTTP请求的方法, 利用它可以模拟浏览器的一个请求发起过程, 同时它还带有处理授权验证( authenticaton )、重定向( redirection 、浏览器 Cookies 及其他内容

以百度为例,把网页抓下来

代码语言:javascript
复制
#!/usr/bin/env python
# coding: utf-8
import urllib.request

response = urllib.request.urlopen("http://www.baidu.com")
print(response.read().decode('utf8'))

运行结果如下:

blob.png
blob.png

这里只用了两行代码,便完成了百度首页的抓取,显示了网页的源代码,得到了源代码之后呢?想要的链接,图片地址,文本信息就可以从中提取出来。

利用type()函数查看response的数据类型

代码语言:javascript
复制
import urllib.request

response = urllib.request.urlopen("http://www.baidu.com")
print(type(response))

输出结果如下:

<class 'http.client.HTTPResponse'>

它是一个HTTPResponse类型的对象,主要包含read(),readinto(),getheader(name),getheaders(name),fileno()等方法以及msg,version,status,reason,debuglevel,closed等属性

调用read()方法可以得到返回的网页内容,调用status属性可以得到返回结果的状态码,如200代表请求成功,404代表网页未找到等。

实例如下:

代码语言:javascript
复制
#!/usr/bin/env python
# coding: utf-8
import urllib.request

response = urllib.request.urlopen("http://www.baidu.com")
print(response.status)
print(response.getheaders())
print(response.getheader('Server'))

运行结果如下:

blob.png
blob.png

利用最基本的urlopen()方法,可以完成最基本的简单网页GET请求抓取。还可以传递一些参数,源码如下:

blob.png
blob.png

除了第一个参数可以传递URL之外,还可以传递其它内容,data(附加数据),timeout(超时时间)等....

参数详情介绍

data参数

data 参数是可选的。如果要添加该参数,并且如果它是字节流编码格式的内容,即 bytes 类型,则需要通过 bytes()方法转化。另外,如果传递了这个参数,则它的请求方式就不再是 GET 方式,而是POST方式.

实例:

代码语言:javascript
复制
#!/usr/bin/env python
# coding: utf-8
import urllib.request
import urllib.parse

data = bytes(urllib.parse.urlencode({'test': 'hello world'}), encoding='utf8')
response = urllib.request.urlopen("http://httpbin.org/post", data=data)
print(response.read().decode('utf8'))

运行结果如下

blob.png
blob.png

注释:上面传递了一个字典,键为test,值为hello wrod,传递过程中需要被转码为bytes(字节流)类型,类型转换用到了bytes()方法,该方法的第一个参数需是str(字符串)类型,而上面传的是一个字典类型,这个时候需要用urllib.parse模块里的urlencode()方法将字典转化成字符串;第二个参数指定编码格式为utf8。

http://httpbin.org/post,这个链接可以用来测试POST请求,传递的参数出现在form字段中,表示模拟了表单提交的方式,以POST方式传递数据。

timeout参数

timeout参数用于设置超时时间,单位为秒,意思就是超过设定的时间,还没有得到响应,就会抛出异常,不指定,使用全局默认时间,支持http,https,ftp请求。

实例:

代码语言:javascript
复制
#!/usr/bin/env python
# coding: utf-8
import urllib.request

response = urllib.request.urlopen("http://httpbin.org/get", timeout=1)
print(response.read().decode('utf8'))

运行结果如下:

blob.png
blob.png

注释:这里设置超时时间为1秒,1秒后没有响应,就会抛出异常,异常属于urllib.error模块

因此,可以通过设置这个超时时间来控制一个网页如果长时间未响应,就跳过它抓取,可以利用try except语句来实现,代码如下:

代码语言:javascript
复制
#!/usr/bin/env python
# coding: utf-8
import urllib.request
import urllib.error
import socket

try:
    response = urllib.request.urlopen("http://httpbin.org/get", timeout=0.1)
except urllib.error.URLError as e:
    if isinstance(e.reason, socket.timeout):
        print("Time out")

运行结果如下:

Time out

注释:这里请求了http://httpbin.org/post测试连接,设置了超时时间为0.1秒,然后捕获了URLError异常,接着判断异常是socket.timeout类型(超时异常),得出确实是超时报错,最后打印Time out, 按照常理0.1秒内不可能得到服务器响应,所有超时,通过设置timeout这个参数来实现超时处理,还是很有用的

其它参数

除了 data 参数和 timeout 参数外,还有 context 参数,它必须是 ssl.SSLContext 类型,用来指定SSL设置, 此外,cafile和capath 这两个参数分别指定 CA 证书和它的路径,这个在请求 HTTPS 链接时会有用,若需要更加详细的文档信息,可以找到python的安装目录,找到Doc目录,下面会有一个pythons354.chrm文档,如下:

blob.png
blob.png

Request

利用urlopen()方法可以实现最基本请求的发起,但这个几个简单的参数并不足以构建一个完整的请求,如果请求中需要加入Headers等信息,就可以利用更强大的Request类来构建

Request用法实例:

代码语言:javascript
复制
#!/usr/bin/env python
# coding: utf-8
import urllib.request

request = urllib.request.Request('http://www.baidu.com')
response = urllib.request.urlopen(request)
print(response.read().decode('utf8'))

注释:依旧是用urlopen()方法来发送这个请求,不过这次该方法的参数不再是URL,而是一个Request类型的对象。通过构造这个数据结构,一方面我们可以将请求独立成一个对象,另一方面可更加丰富和灵活地配置参数。

Request构造源码如下:

blob.png
blob.png

第一个参数url用于请求URL,这是比传参数,其它都是可选

第二个参数data,如果需要传,必须传bytes(字节流)类型的。如果是字典,先用urllib.parse模块里的urlencode()编码

第三个参数 headers 是一个字典,它就是请求头, 在构造请求时通过 headers 参数直接构造,也可以通过调用请求实例的 add_header()方法添加。添加请求头最常用的用法就是通过修改 User-Agent 来伪装浏览器,默认的 User-Agent是Python-urllib,可以通过修改它来伪装成浏览器。

第四个参数 origin_req_host 指的是请求方的 host 名称或者 IP 地址。

第五个参数unverifiable 表示这个请求是否是无法验证的,默认是 False ,意思就是说用户没有足够权限来选择接收这个请求的结果。例如,请求一个HTML 文档中的图片,但是没有自动抓取图像的权限,这时 unverifiable 的值就是 True。

第六个参数method是一个字符串 ,用来指示请求使用的方法,比如 GET, POST, PUT等

实例,传入多个参数构建请求:

代码语言:javascript
复制
#!/usr/bin/env python
# coding: utf-8
from urllib import request,parse

url = 'http://httpbin.org/post'
headers = {
    'User-Agent': 'Mozilla/4.0 (compatible; MSIE S. S; Windows NT)',
    'Host': 'httpbin.org',
}
dict = {
    'name': 'zhangsan'
}

data = bytes(parse.urlencode(dict), encoding='utf8')
req = request.Request(url=url, data=data, headers=headers, method='POST')
response = request.urlopen(req)
print(response.read().decode('utf8'))

运行结果如下;

blob.png
blob.png

注释:通过4个参数构造了一个请求,其中url即请求URL,headers中指定了User-Agent和Host,参数data用urloncode()和bytes()方法转成字节流,还指定了请求的方式为POST

通过上面的结果可以看出,成功设置了data,headers和method,另外headers也可以用add_header()方法来添加

req = request.Request(url=url, data=data, method='POST')

req .add_header('User-Agent', 'Mozilla/4 .0 (compatible; MSIE 5.5; Windows NT )')

这样更加方便地构造请求,实现请求的转发

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-08-27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档