urllib库的使用
urllib包里有五个模块
1. request:负责打开读取url
2. response :处理response对象
3. error:处理request里可能引发的error
4. parse:解析urls
5. robotparser:解析robots.txt 文件
request.urlopen
- url参数
path = "https://www.baidu.com/"
urllib.request.urlopen(path)
req = urllib.request.Request(path)
# 构建Request对象
print(urllib.request.urlopen(req))
urlopen()返回response对象
# <http.client.HTTPResponse>
response = urllib.request.urlopen(req)
response.read().decode('utf-8')
# read() 返回bytes类型字符串
- data参数
根据HTTP规范,GET用于信息获取,POST是向服务器提交数据的一种请求
urlopen的data参数默认为None,若不对其进行设置,则请求采用GET方式,也就是我们从服务器获取信息
如果设置了data参数,则HTTP请求采用POST方式,也就是我们向服务器传递数据data参数有自己的格式,它是一个基于application/x-www.form-urlencoded的格式,我们可以使用urllib.parse.urlencode()函数将字符串自动转换成上面所说的格式。
接下来用一个实例来说明:
先进入开发者模式,Network–XHR–Headers
XHR:XMLHttpRequest (XHR)对象可以与服务器交互。
我们这里需要向服务器传入我们需要翻译的词语 hello
并将Form Data项内容改成字典
获取Request URL,可以看到:
from urllib import request
from urllib import parse
import json
if __name__ == "__main__":
#对应上图的Request URL
Request_URL = 'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule'
#创建Form_Data字典,存储上图的Form Data
Form_Data = {}
Form_Data['i'] = 'hello'
Form_Data['from'] = 'AUTO'
Form_Data['to'] = 'AUTO'
Form_Data['smartresult'] = 'dict'
Form_Data['client'] = 'fanyideskweb'
Form_Data['doctype'] = 'json'
Form_Data['version'] = '2.1'
Form_Data['keyfrom'] = 'fanyi.web'
Form_Data['action'] = 'FY_BY_REALTIME'
Form_Data['typoResult'] = 'false'
# 使用urlencode方法转换标准格式
data = parse.urlencode(Form_Data).encode('utf-8')
#使用urlencode方法转换标准格式
#传递Request对象和转换完格式的数据
response = request.urlopen(Request_URL, data)
# 这里获得的response可以在浏览器(chrome)里看到/Preview、Respinse选项
html = response.read().decode('utf-8')
translate_results = json.loads(html)
translate_results = translate_results['translateResult'][0][0]['tgt']
print("翻译的结果是:%s" % translate_results)
# 翻译的结果是:你好
[参考链接](https://blog.csdn.net/c406495762/article/details/59095864)
response对象其它实例方法:
- response.info() 返回meta标签的信息和服务器的一些信息
- response.geturl() 返回url字符串
- response.getcode() 返回http状态码,200表示成功
error
官方文档介绍里写了URLError和HTTPError,查看代码后发现多了个ContentTooShortError,当下载大小部分和内容长度时引发错误。URLError是OSError的子类,HTTPError和ContentTooShortError都是URLError的子类。服务器上HTTP的响应会返回一个状态码,根据这个HTTP状态码,我们可以知道我们的访问是否成功。对response对象使用getcode()方法能够获取状态码,200表示请求成功,404等则就是常见的错误了。
1. URLError
from urllib import error
from urllib import request
url = "https://_zhaowendao_.com/"
try:
response = request.urlopen(url)
html = response.read()
except error.URLError as e:
print(e)
print(e.reason)
# <urlopen error [WinError 10060] 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。>
# [WinError 10060] 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。
2. HTTPError
from urllib import error
from urllib import request
url = "https://www.csdn.net/zhaowendao"
try:
response = request.urlopen(url)
html = response.read()
except error.HTTPError as e:
print(e)
print(e.code)
print(e.msg)
# HTTP Error 404: Not Found
# 404
# Not Found
3.URLError和HTTPError混合使用
如果想用HTTPError和URLError一起捕获异常,那么需要将HTTPError放在URLError的前面,因为HTTPError是URLError的一个子类。如果URLError放在前面,出现HTTP异常会先响应URLError,这样HTTPError就捕获不到错误信息了。
如果不用上面的方法,也可以使用hasattr函数判断URLError含有的属性,如果含有reason属性表明是URLError,如果含有code属性表明是HTTPError。虽然HTTPError继承自URLError, 但是并没有调用父类的init(使用super),因此不具备父类的属性, 只继承了方法。
from urllib import error
from urllib import request
url = "https://www.csdn.net/zhaowendao"
try:
response = request.urlopen(url)
html = response.read()
except error.URLError as e:
if hasattr(e, "code"):
print("HTTPError")
elif hasattr(e, "reason"):
print("URLError")
# HTTPError
读取json格式字符串
import json
json.loads(str)
# str to dict
json.load(file)
# file to dict
json.dumps(dict)
# dict to str
with open("XXX.txt", 'w') as file
json.dump(dict, file)
# dict to file
chardet检测网页编码
import chardet
import urllib.request
html = urllib.request.urlopen(path).read()
print(chardet.detect(html))
# {'encoding': 'utf-8', 'confidence': 0.99, 'language': ''}