urllib库
一、urllib简介
urllib 是一个用来处理网络请求的python内置标准库,它包含4个模块
- urllib.request:HTTP请求模块,用于模拟浏览器发起网络请求
- urllib.parse:解析模块,用于解析URL
- urllib.error:异常处理模块,用于处理request引起的异常
- urllib.robotparser:用于解析robots.txt文件,应用较少
二、发送请求(request)
1.urlopen()
(1).参数
def urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
- url:字符串类型的URL,必须参数
- data:附加数据,data参数是bytes(字节流)类型。urlopen默认会发送get请求,当传入data参数时,则会发起POST请求
- timeout:超时时间,单位秒。如果请求超过设置时间,没有返回响应,则抛出异常。timeout没有指定则用系统默认设置,timeout只对,http,https以及ftp连接起作用。可以通过控制超时时间跳过抓取长时间未响应的网页
- cafile:CA证书
- capath:CA证书路径
- cadefault:默认为False
- context:指定SSL设置,必须是ssl.SSLContext类型
(2).应用
import urllib.request
response = urllib.request.urlopen(url='https://httpbin.org')
print(type(response)) # <class 'http.client.HTTPResponse'>
# 响应为HTTPResponse类型的对象,包含很多方法和属性
# 调用read()方法得到返回的网页内容
print(response.read().decode('utf-8')) # 网页源代码
# 调用getheaders()方法得到列表形式的响应头信息
print(response.getheaders())
# 调用info()方法获取响应头信息
print(response.info())
# 调用geturl()方法获取访问的url
print(response.geturl()) # https://httpbin.org
# 调用getcode()方法返回状态码
print(response.getcode()) # 200
# 调用status属性获得响应的状态码
print(response.status) # 200
2.Request()
(1).参数
class urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)
-
url:用于请求URL,必须参数
-
data:附加数据,data参数必须是bytes类型
-
headers:请求头,是一个字典。通过urllib发送的请求会有一个默认的headers:
“User-Agent”:“Python-urllib/3.6”
,指明请求是由urllib发送的。遇到一些验证User-Agent的网站时,需要我们自定义headers把自己伪装起来- 伪装成火狐浏览器
headers = {'User-Agent': 'Mozilla/5.0 (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11'}
-
origin_req_host:请求方的host名称或者IP地址
-
unverifiable:是否是无法验证的,默认为False
-
method:指明请求使用的方法,GET、POST等
(2).应用
import urllib.request
# 伪装成火狐浏览器
headers = {'User-Agent': 'Mozilla/5.0 (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11'}
# 构造请求
request = urllib.request.Request(url='http://httpbin.org/post', data=b"name=zzh", headers=headers, method='POST')
response = urllib.request.urlopen(request)
print(response.read().decode('utf-8'))
**********************************************************************
{
"args": {},
"data": "",
"files": {},
"form": {
"name": "zzh"
},
"headers": {
"Accept-Encoding": "identity",
"Content-Length": "8",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "Mozilla/5.0 (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11"
},
"json": null,
"origin": "218.24.192.193, 218.24.192.193",
"url": "https://httpbin.org/post"
}
(3).操作Cookies
from urllib import request
from http import cookiejar
# 创建一个cookie对象
cookie = cookiejar.CookieJar()
# 创建一个cookie处理器
cookies = request.HTTPCookieProcessor(cookie)
# 以它为参数创建Opener对象
opener = request.build_opener(cookies)
# 使用此opener发送请求
response = opener.open("http://www.baidu.com")
print(cookies.cookiejar)
***********************************************************************
<CookieJar[<Cookie BAIDUID=D15F91F4B5D72460F4DB988ABBEA8148:FG=1 for .baidu.com/>, <Cookie BIDUPSID=D15F91F4B5D72460F4DB988ABBEA8148 for .baidu.com/>,
<Cookie H_PS_PSSID=28117_1439_21118_29568_29700_29221_26350_28702 for .baidu.com/>, <Cookie PSTM=1571570176 for .baidu.com/>, <Cookie delPer=0 for .baidu.com/>,
<Cookie BDSVRTM=0 for www.baidu.com/>, <Cookie BD_HOME=0 for www.baidu.com/>]>
(4).代理
from urllib import request
url = 'http://httpbin.org/ip'
# 代理地址
proxy = {'http': '221.182.89.234:63000'}
# 代理处理器
proxies = request.ProxyHandler(proxy)
# 创建Opener对象
opener = request.build_opener(proxies)
# 使用此opener发送请求
response = opener.open(url)
print(response.read().decode())
***********************************************************************
{
"origin": "221.182.89.234, 221.182.89.234"
}
三、解析链接
1.urlparse()
实现URL的识别和分段
def urlparse(url, scheme='', allow_fragments=True)
参数:
- url:待解析的url
- scheme:默认的协议,URL如果没有带协议,则此协议作为默认的协议
- allow_fragments:是否允许锚点显示,默认为True
from urllib.parse import urlparse
result = urlparse('http://www.baidu.com/index.html;user?id=1#comment')
print(type(result), result)
**********************************************************************
<class 'urllib.parse.ParseResult'> ParseResult(scheme='http', netloc='www.baidu.com', path='/index.html', params='user', query='id=1', fragment='comment')
解析结果:
- scheme:协议
- netloc:域名
- path:路径
- params:参数
- query:查询条件,一般用于GET类型的URL
- fragment:锚点
2.urlunparse()
与上述方法相反,此方法构造出一个URL
参数:可迭代对象[scheme, netloc, url, params, query, fragment],元素个数必须为6
from urllib.parse import urlunparse
data = ['http', 'www.baidu.com', '/index.html', 'user', 'id=1', 'comment']
result = urlunparse(data)
print(type(result), result)
**********************************************************************
<class 'str'> http://www.baidu.com/index.html;user?id=1#comment
3.urljoin()
URL的拼接与生成
def urljoin(base, url, allow_fragments=True)
参数:
- base:基础链接
- url:新的链接
- allow_fragments:是否允许锚点显示,默认为True
当参数url与base都有域名且域名不同或参数base无域名时,使用参数url生成URL
当参数base有域名且url仅为参数时,拼接生成URL
from urllib.parse import urljoin
result1 = urljoin('https://www.baidu.com', "https://www.sougou.com")
print(type(result1), result1)
result2 = urljoin('', "https://www.sougou.com")
print(type(result2), result2)
result3 = urljoin('https://www.baidu.com', "id=1")
print(type(result3), result3)
**********************************************************************
<class 'str'> https://www.sougou.com
<class 'str'> https://www.sougou.com
<class 'str'> https://www.baidu.com/id=1
4.urlencode()
利用字典构造GET请求的方法
from urllib.parse import urlencode
params = {
'id': 1,
"page": 2,
}
result = 'https://www.baidu.com?' + urlencode(params)
print(type(result), result)
**********************************************************************
<class 'str'> https://www.baidu.com?id=1&page=2
5.parse_qs()
与上述方法相反,将参数转化为字典
from urllib.parse import parse_qs
result = parse_qs('id=1&page=2')
print(type(result), result)
**********************************************************************
<class 'dict'> {'id': ['1'], 'page': ['2']}
6.quote()
将内容(中文等等)转化为URL编码的格式
from urllib.parse import quote
name = "志昊"
result = 'https://www.baidu.com/login?name=' + quote(name)
print(type(result), result)
**********************************************************************
<class 'str'> https://www.baidu.com/login?name=%E5%BF%97%E6%98%8A
7.unquote()
与上述方法相反,将URL解码
from urllib.parse import unquote
url = "https://www.baidu.com/login?name=%E5%BF%97%E6%98%8A"
result = unquote(url)
print(type(result), result)
**********************************************************************
<class 'str'> https://www.baidu.com/login?name=志昊
四、处理异常
1.URLError
URLError是error异常模块的基类,由request模块产生的异常都可以用这个类来处理
from urllib import request,error
url = "https://www.cuowuurl.com"
try:
result = request.urlopen(url)
except error.URLError as e:
print(e.reason)
**********************************************************************
[Errno 11001] getaddrinfo failed
2.HTTPError
HTTPError是URLError的子类,主要用于处理HTTP请求错误
属性:
- code:HTTP状态码
- reason:错误原因
- headers:请求头
from urllib import request,error
url = "https://www.douban.com/index=111111"
try:
result = request.urlopen(url)
except error.HTTPError as e:
print(e.code, e.reason, e.headers)
**********************************************************************
418 Date: Fri, 29 Nov 2019 05:09:50 GMT
Content-Length: 0
Connection: close
Server: dae
五、分析Robots协议
1.Robots协议
Robots协议(也称为爬虫协议、机器人协议等)的全称是“网络爬虫排除标准”(Robots Exclusion Protocol),网站通过Robots协议告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取
2.robotparse
- robotparse模块主要负责处理爬虫协议文件,robots.txt.的解析
- robots.txt是一个协议,而不是一个命令
- robots.txt是搜索引擎中访问网站的时候要查看的第一个文件
- robots.txt文件告诉蜘蛛程序在服务器上什么文件是可以被查看的
- robots.txt文件是一个文本文件,使用任何一个常见的文本编辑器即可可以创建和编辑它
3.搜索引擎爬虫名称
爬虫名称 | 公司 | 网站 |
---|---|---|
BaiduSpider | 百度 | www.baidu.com |
Googlebot | 谷歌 | www.Google.com |
360Spider | 360搜索 | www.so.com |