声明:本文知识点解释部分大部分来自21天搞定Python分布式爬虫教学视频
urllib库是Python中一个基本的网络请求库。可以模拟浏览器的行为,向指定的服务器发送一个请求,并可以保存服务器返回的数据。
在Python3的urllib库中,所有和网络请求相关的方法,都被集成到了urllib.request模块下面了。
基本用法:
from urllib import request # 从urllib导入request库
resp = request.urlopen('http://www.baidu.com')
print(resp.read()) # 读取百度网页的源代码,并打印
下面对urlopen进行详细说明:
http.client.HTTPResponse对象有read(< size >)、readline()、readlines()、getcode()等方法
该函数可以将某个url下载到本地。
基本用法:
from urllib import request
request.urlretrieve('http://www.baidu.com/', 'baidu.html')
该语句表示:将www.baidu.com
的源码下载到本地的一个文件夹中,并命名为baidu.html
。
此外,还可以用该函数从网站上下载一个图片,比如:
from urllib import request
request.urlretrieve('https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1593714637497&di=3909581542fd82fdb24e5e3edebd975b&imgtype=0&src=http%3A%2F%2Fa0.att.hudong.com%2F56%2F12%2F01300000164151121576126282411.jpg', 'image1.jpg')
在浏览器上进行搜索时,如果url中包含了中文或者其他特殊字符,那么浏览器会自动的对这些内容进行编码,并且如果将这段URL
复制到文本文件或者是IDE中,相应的部分也会被自动编码。但是,如果用代码发出请求,那么必须对这些内容手动进行编码,否则会报错。此时可以利用urlencode
函数实现。urlencode
函数可以将字典数据转换为URL
编码的数据。
没有手动编码的代码:
from urllib import request
url = 'https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=刘德华'
resp = request.urlopen(url)
print(resp.read())
报错:UnicodeEncodeError: 'ascii' codec can't encode characters in position 51-53: ordinal not in range(128)
经过手动编码的代码:
from urllib import request
from urllib import parse # urlencode需要导入parse库
url = 'https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&'
params = {'wd': '刘德华'} # 需要编码的部分,放入一个字典中
qs = parse.urlencode(params) # 进行编码,返回一个字符串
url = url + qs # 加到url后面
resp = request.urlopen(url)
print(resp.read())
此时可以正常运行
parse_qs
与urlencode
互为逆过程,即解码。比如:
from urllib import request
from urllib import parse # parse_qs也需要导入parse库
params = {'name': '百度', 'age': '18', 'motto': 'hello world'}
qs = parse.urlencode(params)
print(qs)
result = parse.parse_qs(qs)
print(result)
在爬虫前缀知识这篇文章中说到,url的由若干个部分组成。而这两个函数可以将这若干个部分分离出来。比如:
from urllib import parse
# 协议: http
# 服务器: www.baidu.com
# 路径: /s
# 查询串: wd=python&username=abc
# 锚点: 1
url = 'http://www.baidu.com/s?wd=python&username=abc#1'
result1 = parse.urlparse(url)
result2 = parse.urlsplit(url)
print(result1)
print(result2)
结果如下:
可以看到,二者的区别在于:urlparse
返回的结果中有params
,而urlsplit
没有