urllib 是一个 python 内置包,不需要额外安装即可使用,包里面包含了以下几个用来处理 url 的模块:
掌握以上四个模块,你就能对网站进行简单的爬虫操作,下面我们逐个介绍。
urllib.request 模块定义了以下几个函数。
该函数主要用于模拟网站请求,返回一个 HTTPResponse 类型的对象。
1.1.1 urlopen 函数中参数定义
1.1.2 urlopen 函数返回类型
urlopen 函数请求返回一个 HTTPResponse 响应上下文,或者请求异常抛出 URLError 协议错误,一般有如下属性:
1.1.3 urlopen 函数的应用实例
# 创建一个 HTTP GET 请求,输出响应上下文 from urllib.request import urlopen response = urlopen("http://www.python.org") print(response.read())
# 创建一个 HTTP POST 请求,输出响应上下文 from urllib.request import urlopen from urllib.parse import urlencode data = {'kw' : 'python'} data = bytes(urlencode(data), encoding = 'utf-8') response = urlopen("https://fanyi.baidu.com/sug", data) print(response.read().decode('unicode_escape'))
# 创建一个 HTTP GET 请求,设置超时时间为0.1s import urllib.request import urllib.error try: response=urllib.request.urlopen('http://www.python.org',timeout=0.1) print(response.read()) except urllib.error.URLError as e: print(e.reason)
该函数主要用于构造一个 url,返回一个 urllib.request.Request 对象。
1.2.1 Request 函数中参数定义
1.2.2 Request 函数返回类型
与 urlopen 函数请求返回一样,一般返回一个 HTTPResponse 响应上下文。
1.2.3 Request 函数的应用实例
# 采用 HTTP GET 请求的方法模拟谷歌浏览器访问网站,输出响应上下文 from urllib import request,parse url = 'http://www.python.org' headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36' } req = request.Request(url, headers = headers, method = 'GET') response = request.urlopen(req) print(response.read())
# 采用 HTTP POST 请求的方法模拟谷歌浏览器访问网站,输出响应上下文 from urllib import request from urllib import parse url = 'https://fanyi.baidu.com/sug' data = {'kw' : 'python'} data = bytes(parse.urlencode(data), encoding = 'utf-8') headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36' } req = request.Request(url, data, headers, method = 'POST') response = request.urlopen(req) print(response.read().decode('unicode_escape'))
# 创建一个 HTTP GET 请求,通过 add_header 添加一个 UserAgent import urllib.request import random url = 'http://www.python.org' headerUserAgentList = ['Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36', 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0'] randomHeaderUserAgent = random.choice(headerUserAgentList) # 随机选取一个 UserAgent req = urllib.request.Request(url) req.add_header('User-Agent', randomHeaderUserAgent) # 添加 UserAgent response=urllib.request.urlopen(req) print(req.get_header('User-agent')) print(req.headers) # 打印请求的 header 信息
urllib.error 模块定义了由 urllib.request 模块引发的异常,异常主要包含 URLError 和 HTTPError。
URLError 类继承自 OSError 类,是 error 异常模块的基类,由request模块产生的异常都可以通过捕获这个类来处理。URLError 只有一个属性 reason,即返回错误的原因。
应用实例:
# 在请求连接时候捕获网址错误引发的异常 from urllib import request, error try: response = request.urlopen('https://www,baidu,com') except error.URLError as e: print(e.reason)
HTTPError 是 URLError 的子类,专门用来处理 HTTP 请求错误,比如认证请求失败,包含以下三个属性:
应用举例:
# 返回401未授权错误 from urllib import request,error try: response=request.urlopen('http://pythonscraping.com/pages/auth/login.php') print(response.getcode()) except error.HTTPError as e: print('1.错误原因:\n%s\n2.状态码:\n%s\n3.响应头信息:\n%s' %(e.reason, e.code, e.headers)) except error.URLError as e: print(e.reason)
urllib.parse 模块定义了一个处理 url 的标准接口,用来实现 url 字符串的抽取、合并以及链接转换。该模块主要用到的函数如下。
用于实现 url 字符串的识别和分段,可以分为六个字符串,分别是 scheme (协议),netloc (域名),path (路径),params (参数),query (查询条件)和 fragment (锚点),其结构如下所示:“scheme://netloc/path;parameters?query#fragment”。实际上具体 url 某些字段可能会不存在,比如 “http://www.baidu.com” 只包含了协议和域名。
3.1.1 urlparse 函数中参数定义
3.1.2 urlparse 的返回类型
函数返回的是一个 urllib.parse.ParseResult 对象,获取解析出来的 url 六个字段。
3.1.3 urlparse 应用举例
# 解析并输出 url 中每个字段的字符串 import urllib url = 'http://www.baidu.com/urllib.parse.html;python?kw=urllib.parse#module-urllib' result = urllib.parse.urlparse(url) print(result) print(result.scheme, result.netloc, result.path, result.params, result.query, result.fragment, sep = '\n')
与 urlparse 相反,通过列表或者元祖的形式将分段的字符串组合成一个完整的 url 字符串。
3.2.1 urlunparse 函数中参数定义
3.2.2 urlunparse 的返回类型
urlunparse 函数返回一个构造好的 url 字符串。
3.2.3 应用举例
# 通过 data 列表或元组构造一个 url 并输出 import urllib dataList = ['http', 'www.baidu.com', '/urllib.parse.html', 'python', 'kw=urllib.parse', 'modul-urllib'] # 六个字符串都必须填写,否则会出现 ValueError 错误,如果某一字符串不存在则填入空字符 dataTuple = ('http', 'www.baidu.com', '/urllib.parse.html', '', 'kw=urllib.parse', 'modul-urllib') # 六个字符串都必须填写,否则会出现 ValueError 错误,如果某一字符串不存在则填入空字符 urlList = urllib.parse.urlunparse(dataList) urlTuple = urllib.parse.urlunparse(dataTuple) print('1.urlList:%s\n2.urlTuple:%s' % (urlList, urlTuple))
与 urlparse 函数类似,但它只返回 url 字符串的5个字段,把 params 合并到 path 中。
urlsplit 应用举例
# 解析并输出 url 中每个字段的字符串,params 会合并到 path 中。 import urllib url = 'http://www.baidu.com/urllib.parse.html;python?kw=urllib.parse#modul-urllib' result = urllib.parse.urlsplit(url) print(result) print(result.scheme, result.netloc, result.path, result.query, result.fragment, sep = '\n')
与 urlunparse 函数类似,它也是将 url 中各部分字段组合完整的 url 字符串的方法,唯一的区别是列表或元组的长度必须是5个,因为它把 params 省略了。
urlunsplit 应用举例
# 通过 data 列表或元组构造一个 url 并输出 import urllib dataList = ['http', 'www.baidu.com', '/urllib.parse.html;python', 'kw=urllib.parse', 'modul-urllib'] # 五个字符串都必须填写,否则会出现 ValueError 错误,如果某一字符串不存在则填入空字符 dataTuple = ('http', 'www.baidu.com', '/urllib.parse.html;python', 'kw=urllib.parse', 'modul-urllib') # 五个字符串都必须填写,否则会出现 ValueError 错误,如果某一字符串不存在则填入空字符 urlList = urllib.parse.urlunsplit(dataList) urlTuple = urllib.parse.urlunsplit(dataTuple) print('1.urlList:%s\n2.urlTuple:%s' % (urlList, urlTuple))
使用 %xx 转义字符替换字符串中的特殊字符,比如汉字。字母、数字和‘_.-~’字符不会被替换。
3.5.1 quote 函数中参数定义
3.5.2 quote 函数的返回类型
quote 函数返回一个编码后的字符串。
3.5.3 应用举例
# 采用 quote 对 url 中的汉字进行编码,输出编码后的结果 import urllib url = 'http://www.baidu.com/爬虫' result = urllib.parse.quote(url) print(result) url = 'http://www.baidu.com/+爬虫' result = urllib.parse.quote(url, '+') # 更改 safe 参数 print(result)
与 quote 函数相反,把 %xx 转义字符替换成字符。
3.6.1 unquote 函数的参数定义
3.6.2 unquote 函数的返回类型
unquote 函数返回一个解码后的字符串。
3.6.3 应用举例
# 解码经过 quote 函数处理后的 url,输出解码后的结果。 import urllib url = 'http://www.baidu.com/爬虫' result = urllib.parse.quote(url) print(result) result = urllib.parse.unquote(url) print(result)
该函数用来将基本 url 与另一个 url 组合,更新基本 url 字符串。它会使用 url 对基本 url 中缺失的部分进行补充,比如 scheme (协议)、netloc (域名)和 path (路径)。即根据 url 字符串中带有的字段,对基本 url 中没有的字段进行补充,已存在的字段进行替换。
3.7.1 urljoin 函数中参数定义
3.7.2 urljoin 函数返回类型
返回组合成功的 url 字符串。
3.7.3 应用举例
# 基于 url 对 base_url 进行重新组合,并输出组合结果。 import urllib base_url = 'http://www.baidu.com' url = 'https://www.google.com/urllib.parse.html;python?kw=urllib.parse#module-urllib' result = urllib.parse.urljoin(base_url,url,False) print(result)
urlencode 函数可以将字典转化为 GET 请求中的 query (查询条件),或者将字典转化为 POST 请求中需要上传的数据。
3.8.1 urlencode 函数中参数定义
3.8.2 urlencode 函数返回类型
urlencode 函数返回 str 字符串。
3.8.3 应用举例
# 创建 GET 请求 import urllib params = {'username':'xxx','password':'123'} base_url='http://www.baidu.com' url=base_url + '?' + urllib.parse.urlencode(params) print(url) params = {'username':['xxx', 'yyy'], 'password':'123'} # username 键对应多个值 base_url='http://www.baidu.com' url=base_url + '?' + urllib.parse.urlencode(params) # doseq 设置为 False,会解析成乱码 print(url) url=base_url + '?' + urllib.parse.urlencode(params, True) # doseq 设置为 True print(url)
rebotparser 模块提供了一个 RobotFileParser 类,主要用来解析网站上发布的 robots.txt,然后根据解析内容判断爬虫是否有权限来爬取这个网页。
robots.txt,存放于网站根目录下,采用 ASCII 编码的文本文件,记录此网站中的哪些内容是不应被爬虫获取的,哪些是可以被爬虫获取的。
robots.txt 文件内容举例
User-agent: * Disallow: / Allow: /public/
应用举例
# 使用两种爬虫代理分别查看是否可以对 'http://www.baidu.com' 网站进行爬取 from urllib.robotparser import RobotFileParser rp = RobotFileParser() rp.set_url("http://www.baidu.com/robots.txt") rp.read() print(rp.can_fetch('Baiduspider', 'http://www.baidu.com')) print(rp.can_fetch('*', 'http://www.baidu.com'))
本节给大家介绍了 Python 中 urllib 包的使用,为 Python 工程师对该包的使用提供了支撑,了解爬取网站所需的一些基本函数操作。