一、使用urllib
urllib库的四大模块:
- urllib.request:最基本的HTTP请求模块,可以用来模拟请求
- urllib.error:异常处理模块
- urllib.parse:一个工具模块,提供了许多URL处理方法,比如拆分、解析、合并等
- urllib.robotparser:用来识别网站的robots.txt文件
(1)发送请求
1、urlopen()
import urllib.request
response = urlib.request.urlopen("https://www.python.org")
print(response.read().decode("utf-8"))
# 编码和解码:
# decode():解码,将括号里的格式解码成unicode编码格式
# encode():编码,将unicode格式的数据编码成括号里的格式
import urllib.request
response = urllib.request.urlopen("https://www.python.org")
print(type(response))
# 结果:<class 'http.client.HTTPResponse'>
根据上面代码的结果分析:它是一个HTTPResponse类型的对象。
主要包含了:
read()、readinto()、getheader(name)、getheaders()、fileno()等方法
msg、version、status、reason、debuglevel、closed等属性
import urllib.request
response = urllib.request.urlopen("https://www.python.org")
print(response.status) # 获取状态码
print(response.getheaders()) # 获取响应头的全部信息
print(response.getheader('Server')) # 获取响应头的指定信息
urlopen()方法,可以完成最基本的GET请求
1.1 data参数
data参数是可选的。
如果要添加该参数,必须将参数进行转码,转为字节型数据
如果使用data参数传递,则请求方式就变为了POST请求方式,不再时GET请求方式
import urllib.parse
improt urllib.request
data = urllib.parse.urlencode({
"world": "Hello"})
data = bytes(data, encodeing="utf8")
response = urllib.request.urlopen("http://httpbin.org/post",
data=data)
print(response.read().decode("utf-8"))
'''
结果:
{
"args": {},
"data": "",
"files": {},
"form": {
"world": "Hello"
},
"headers": {
"Accept-Encoding": "identity",
"Content-Length": "11",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "Python-urllib/3.6",
"X-Amzn-Trace-Id": "Root=1-601527bc-6cc1b04e0aa3fd946d2f48a6"
},
"json": null,
"origin": "101.27.236.254",
"url": "http://httpbin.org/post"
}
'''
传递的参数在结果中的from字段中,这表明是模拟了表单的提交方式,以POST方式传输数据。
1.2 timeout参数
用于设置超时时间的参数,单位是秒。
如果请求超出了设定的时间,还没有得到响应,就会抛出异常。如果不指定该参数就会使用全局默认时间。
import urllib.request
response = urllib.request.urlopen("http://httpbin.org/get",
timeout=0.1)
print(response.read())
'''
结果:
urllib.error.URLError: <urlopen error timed out>
'''
上面代码是在请求的时候设置了超时时间为0.1秒。这个请求在0.1秒内并没有得到任何响应。于是抛出了URLError异常,这异常属于urllib.error模块,错误原因是超时。
知道这个参数的使用。因此可以通过设置这个超时时间来控制一个网页,如果长时间未响应,就跳过它的抓取。可以使用try except语句来实现:
import socket
import urllib.request
import urllib.error
try:
response = urllib.request.urlopen("http://httpbin.org/get",
timeout=0.1)
except urllib.error as e:
if isinstance(e.reason, socker.timeout):
print("TIME OUT")
'''
结果:TIME OUT
isinstance(object, classinfo):判断object是否是属于classinfo
e.reason:也就是urllib.error下面的reason属性是抛出异常的原因
if语句是判断:该异常原因是否属于socket.timeout。如果是就打印TIME OUT
经过if判断从而得出确实是因为超时而报错的
'''
1.3 其他参数
context:必须是 ssl.SSLContext类型 , 用来指定SSL设置
cafile:指定CA证书
capath:指定CA证书的路径
CA证书在请求HTTPS链接时会有用
2、Requst
前面利用urlopen()方法即可进行简单的请求,但是如果在请求中加入Headers的就需要使用Request()方法来构建了
import urllib.request
request = urllib.request.Request("https://python.org")
response = urllib.request.urlopen(request)
print(response.read().decode("utf-8"))
看上面的代码。还是依旧使用了urlopen()方法,但是之前请求的是一个链接,现在请求的是一个Request类型的对象。
class urllib.request.Request(url,
data=None,
headers={
},
origin_req_host=None,
unverifiable=False,
method=None
)
url:用于请求的URL,必传参数,其他参数都是可选参数
data:必须传bytes(字节流)类型的。如果是字典,可以使用urllib.parse模块里的
urlencode()方法编码
headers:请求头
origin_req_host:请求方的host名称和IP地址
unverifiable:是否无法验证的,默认是False。也就是说用户没有足够权限来选择接
接受这个请求的结果。
例如:我们请求一个HTML文档中的图片,但是没有自动抓取图片的权
限,这时的unverifiable的值就是True。
method:请求方式,例如GET、POST、PUT等
from urllib import request, parse
url = "http://httpbin.org/post"
headers = {
"User-Agent": "此处省略,
"Host"