目录
-
urllib简介
简单了解一下urllib库,它是Python中的一个内置基础的Http请求库,不需要安装,拥有四个主要模块,如下:
模块 | 简介 |
---|---|
urllib.request | 发起网络请求,打开和读取URL |
urllib.error | 处理HTTP或URL等异常 |
urllib.parse | 解析URL链接 |
urllib.robotparser | 解析robots.txt文件 |
-
一般用法
一、使用库
from urllib import request,error #用于请求、headers更改、IP代理等等
from http import cookiejar #用于设置cookie
import time #主用于time.sleep()休眠,防止访问过于频繁
import chardet #用于解码HTML
import socket #用于判断异常
二、使用url和headers生成一个Request对象,然后将其传入urlopen方法中
#自定义头部信息User_Agent,模拟浏览器访问
url = 'http://httpbin.org/get'
headers = {'user-agent': 'Mozilla/5.0...'}
#需要使用url和headers生成一个Request对象,然后将其传入urlopen方法中
req = request.Request(url, headers=headers) #Request对象实例化
rsp = request.urlopen(req)
print(rsp.read().decode()) #decode()为解码方法,自动的将二进制格式转码成当前编辑器环境的格式,通常为UTF-8,也可指定解码方式,如decode('gbk')
#特别注意:
#1、request.urlopen()请求方法不能像其他第三方库(如Requests库的request请求)一样直接传入headers等参数,需要使用request.Request()方法将Request对象实例化,然后传入urlopen()。
#2、rsp返回的访问结果是一个HTTPResponse对象,使用该对象的read()方法即可获取访问网页获取的数据,这个数据是二进制格式的,所以我们还需要使用decode()方法来将获取的二进制数据进行解码,转换成看的懂得字符串
三、在urllib中主要设置了两个异常,一个是URLError,一个是HTTPError,HTTPError是URLError的子类。
1、URLError:有.reason一个属性,用来抓取异常并打印自定义错误信息;
2、HTTPError:有.code,.reason,.headers等三个属性,在抓取异常时可获得code,reson,headers三个信息,用于分析异常
具体用法如下:
#异常处理
try:
response = request.urlopen("http://www.baidu.com")
#判断url异常(一般来说设置URL异常处理就可以了)
except error.URLError as e:
print(e.reason)
if isinstance(e.reason,socket.timeout):
print("time out")
#判断HTTP异常
except error.HTTPError as e:
print(e.reason)
print(e.code)
print(e.headers)
else:
print("reqeust successfully")
#isinstance(object, classinfo)
#判断两个类型是否相同,如果object对象的类型与参数二的类型(classinfo)相同则返回 True,否则返回 False。
四、代理IP的基本原理:以本机先访问代理IP,再通过代理IP地址访问服务器,从而使服务器接受到的访问是代理IP。
#设置IP代理池
from urllib import request
import random #python的内置库,主要用于生成伪随机数
url = 'http://www.baidu.com/'
proxy_IP = [
{'http': '218.18.232.26:80'},
{'https': '218.18.232.26:80'}
]
proxies = request.ProxyHandler(random.choice(proxy_IP)) # 创建代理处理器
opener = request.build_opener(proxies) # 创建opener对象
resp = opener.open(url)
print(resp.read().decode())
在上述的方法中,我们用到了request.build_opener()
方法代替request.urlopen()
方法,其实urlopen()
就是通过构造好了的opener对象发送请求,在这里我们使用request.build_opener()
方法重构了一个opener()
对象,我们可以通过这个对象实现urlopen()
实现的任何东西,包括网络URL请求等。
五、当我们需要进行翻页或者跳转等其它操作,为了防止无法访问我们想要的数据,需要让网站识别我们是同一个用户。这个时候我们就需要带上cookie进行访问。
由于urllib并没有很好的处理cookie的对象,所以在这里我们需要用到一个别的库来设置cookie,即http库,并使用里面的cookiejar来进行cookie的管理。
#设置cookie
from http import cookiejar
from urllib import request
#方法一:
url = 'https://www.baidu.com'
# 创建一个cookiejar对象
cookie = cookiejar.CookieJar()
# 使用HTTPCookieProcessor创建cookie处理器
cookies = request.HTTPCookieProcessor(cookie)
# 并以它为参数创建Opener对象
opener = request.build_opener(cookies)
#把opener设置为全局
#request.install_opener(opener)
# 使用这个opener来发起请求
resp = opener.open(url)
# 查看之前的cookie对象,则可以看到访问百度获得的cookie
for i in cookie:
print(i)
#方法二:
#也可以直接在headers设置cookie
headers = {'User':'Mozilla/5.0...',
'cookie':'个人cookie'
}
req = request.Request(url, headers=headers, timeout=0.1)
rsp = request.urlopen(req)
html = rsp.read().encode()
如果把这个生成的opener对象使用install_opener方法来设置为全局的,opener对象之后的每次访问都会带上这个cookie。设置全局后既可以用urlopen()方法, 也可以用opener.open() ;将这个opener设置为全局的opener,之后所有的,不管是opener.open()还是urlopen() 发送请求,都将使用自定义
request.install_opener(opener)
resp = request.urlopen(url)
-
其他用法
1、ssl证书异常,选择忽略证书验证
import ssl
from urllib import request
context = ssl._create_unverified_context()
res=urllib.request.urlopen(request, context=context)
2、若不设定data,默认为get请求(即data=None),可更改为post请求,如下:
import urllib.request, urllib.parse
data = bytes(urllib.parse.urlencode({'word': 'hello'}), encoding='utf8')
resp = urllib.request.urlopen('http://www.baidu.com/post', data=data) #注意:传递的data数据需要为bytes格式
3、data参数需要用urllib.parse模块对其进行数据格式处理。
from urllib import parse
#将特殊字符进行url编码,转换成可以使用url传输的格式(默认ASCII)
parse.quote("底特律", encoding='utf-8') #或gbk
#对URL解码为中文或其他可识别字符
parse.unquote('%E5%BA%95%E7%89%B9%E5%BE%8B',encoding='utf-8')
#将字典转换为url参数
from urllib import parse
paramers = {'address':'底特律','phone':'123456789','name':'Connor'}
parse.urlencode(paramers,encoding='utf-8')
#运行结果:'address=%E5%BA%95%E7%89%B9%E5%BE%8B&phone=123456789&name=Connor'
4、查看request请求情况
from urllib import request
file = request.urlretrieve("www.baidu.com")
file.getcode() #获取页面请求的状态码
file.geturl() #获取URL信息
file.info() #获取头部信息
5、如果该网页使用的不是utf-8,又或者你懒得亲自去查看一下正确的解码方式,那么可以使用chardet来进行解析。
import chardet
res = request.urlopen("http://www.baidu.com/")
html = res.read()
charset = chardet.detect(html)['encoding']
常用urllib请求的完整代码如下:
from urllib import request,error
from http import cookiejar
import time
import socket
url = 'https://www.baidu.com'
headers = {'User_Agent': 'Mozilla/5.0...'}
#异常处理
try:
#自定义头部信息User_Agent,模拟浏览器访问
req = request.Request(url, headers=headers,timeout=0.1)
#发送请求
rsp = request.urlopen(req)
#读取并解码文件格式
html = rsp.read().encode()
# 写入文件txt
f = open('html.txt', 'w', encoding='utf8')
f.write(html)
#休眠1秒
time.sleep(1)
except error.URLError as e:
print(e.reason)
#异常判断并打印字符串
if isinstance(e.reason,socket.timeout):
print("time out")
-
urllib库与request库之粗浅对比
经过上述自我学习了解,可以发现urllib库使用起来还是比较繁琐麻烦的,如加入headers、cookie、使用IP代理池等都需要创建相应的对象,虽然有urllib.parse模块可以很好的处理URL数据格式,但总体上没有request库使用起来顺手,驼某人还是略喜欢简单粗暴的request库;最后想说,如果发现request库爬取不了HTML的话,还是可以尝试一下使用urllib库的喔!
若有朋友想了解它们更多的详细区别,可以自行搜索,已有很多优秀的文章介绍,我就不再重复累赘了,若懒得搜索,这里有一篇介绍得很好的文章【Python爬虫】requests与urllib库的区别,可借鉴一下!
以上为本文全部内容,如有错误,麻烦不吝指教,相互学习,勉励前行,谢谢!