网络请求模块就是帮助浏览器(客户端)向服务器发送请求的
在Python3
之前的版本(Python2
版本)中所使用的网络请求模块是 urllib
模块
在Python3
现在的版本中通过 urllib
模块进行升级 有了现在所使用的 requests
模块,也就是 requests
模块是基于 urllib
模块进行开发的
urllib
模块: urllib
库是Python内置的HTTP
请求库,urllib
模块提供的上层接口,使访问 www
和 ftp
上的数据就像访问本地文件一样
urllib
库中有以下几种模块:
urllib.request
– 请求模块urllib.parse
– url
解析模块urllib.error
– 异常处理模块urllib.robotparser
– robots.txt
解析模块(1)urllib.request
模块:
urllib.request
模块提供了最基本的构造HTTP
请求的方法,利用它可以模拟浏览器的一个请求发起过程,同时它还带有处理authenticaton
(授权验证);redirections
(重定向);cookies
(浏览器Cookies
)以及其它的内容
常用的方法:
urllib.request.urlopen("网址" / "请求对象")
:向网站发起一个请求并获取响应 ,urlopen()
方法不支持重构User-Agent
urllib.request.Request("网址" , headers = "字典")
:返回一个请求对象(封装成请求对象)read()
:读取服务器响应的内容response.read()
response.read().decode("utf-8")
getcode()
:返回HTTP的响应码geturl()
:返回实际数据的url
(防止重定向问题)
urllib.request.urlopen("网址" / "请求对象")
示例 – 以爬取百度首页为示例:
# urllib是一个内置库,内置库是不用我们通过pip工具进行安装的,直接导入即可
import urllib.request
# 目标url
url = "http://www.baidu.com"
# 发起请求
response = urllib.request.urlopen(url) #当前response返回的是一个响应对象
#这个参数我们不仅可以传入一个网址;也可以传入一个对象
# 获取响应
# html = response.read() #获取字节流(返回的是二进制数据)
html = response.read().decode('utf-8') #获取字符串(将其编码成字符串)
# print(html)
print(response.getcode()) #返回HTTP的响应码
print(response.geturl()) #返回实际数据的URL
#缩写版,三行代码搞定
import urllib.request
html = urllib.request.urlopen("https://www.douban.com/").read().decode("utf-8")
print(html)
如何查看函数说明:
(1)将鼠标放置在要查看的函数上,按CTRL + B
(2)将鼠标放置在要查看的函数上,按住CTRL
再点击鼠标左键
urllib.request.Request("网址", "请求头")
示例 – 以爬取豆瓣首页为示例:
由上我们知道利用urlopen()
方法可以实现最基本的请求,但在遇到反爬时,仅凭这几个简单的参数还不足以构成一个完整的请求,如果在请求中需要加入headers
等信息,我们就需要利用更强大的Request
方法来构建一个请求
import urllib.request
# 目标url
url = "https://www.douban.com/"
#请求头信息: 请求头一定要是字典的形式,在复制粘贴时也不要多出空格
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36"
}
# 1 创建请求对象并构建User-Agent
req = urllib.request.Request(url, headers=headers) #此时req是一个请求对象
print(req) #打印请求对象
# 2 获取响应对象 urlopen
"""
我们依然是用urlopen()方法来发送这个请求,只不过这次urlopen()方法的参数不再是一个URL,
而是一个Request请求对象,通过构造这个请求头信息。一方面我们可以将请求独立成一个对象,另一方面可配置参数更加丰富和灵活
"""
response = urllib.request.urlopen(req)
# 3 读取响应对象的内容 read().decode("utf-8")
html = response.read().decode("utf-8")
print(html)
(2)urllib.parse
模块:
常用方法:
1. urlencode
(这个里面传入的参数类型是字典)
传入参数类型:字典
功能:将存入的字典参数编码为URL查询字符串,即转换成以key1=value1&key2=value2
的形式
&:连接符,连接参数与参数之间的
导入:from urllib.parse import urlencode
2. quote
(这个里面的参数是字符串)
对url
单个字符串编码
urlencode
与quote
代码示例:以海贼王页面的URL
为示例:
# 网络模块在向一个携带一个中文字样的url发送请求就会出现问题
# 解决方案: 把中文处理成%+十六进制的样式
import urllib.request
import urllib.parse
url1 = "https://www.baidu.com/s?wd=%E6%B5%B7%E8%B4%BC%E7%8E%8B"
#url2 = "https://www.baidu.com/s?wd=海贼王"
#url3 = "https://www.baidu.com/s?wd=python"
req = urllib.request.urlopen(url1) #正常返回请求对象
#req = urllib.request.urlopen(url2)
'''报错,如果在url中出现中文,会报出现编码的错误,但如果用的是Requests模块就不会报这个错误了,因为中文被Requests模块直接处理了'''
#req = urllib.request.urlopen(url3) #正常返回请求对象
print(req)
# 第一种方法 -- 用 urlencode()方法
r = {"wd": "海贼王"}
result = urllib.parse.urlencode(r) # 对r进行解码
print(result)
f_url = "https://www.baidu.com/s?" + result
print(f_url)
# 第二种方法 -- 用 quote()方法
r = "海贼王"
result = urllib.parse.quote(r) # 对r进行解码
print(result)
f_url = "https://www.baidu.com/s?wd=" + result
print(f_url)
(3)用urllib
保存图片实例分析:
如何找到图片当前的
url
:
当前页面的网址并不等于是这张图片的网址
可以通过鼠标右键点击检查的方式去查找这个图片的url
/ 右键点击复制图片地址(链接)
一:
urlretrieve
方法:
参数说明:
url
:外部或者本地url
filename
:指定了保存到本地的路径(如果未指定该参数,urllib
会生成一个临时文件来保存数据)
reporthook
:是一个回调函数,我们可以利用这个回调函数来显示当前的下载进度
data
:指post
到服务器的数据。该方法返回一个包含两个元素的元组(filename
,headers
),filename
表示保存到本地的路径,header
表示服务器的响应头
from urllib.request import urlretrieve
url = "https://ts1.cn.mm.bing.net/th/id/R-C.66d7b796377883a92aad65b283ef1f84?rik=sQ%2fKoYAcr%2bOwsw&riu=http%3a%2f%2fwww.quazero.com%2fuploads%2fallimg%2f140305%2f1-140305131415.jpg&ehk=Hxl%2fQ9pbEiuuybrGWTEPJOhvrFK9C3vyCcWicooXfNE%3d&risl=&pid=ImgRaw&r=0"
urlretrieve(url=url, filename="mao.png")
二:
reuqest
方法:
import requests
url = "https://ts1.cn.mm.bing.net/th/id/R-C.0b10c2b8abae5557d767f78345c7c3b9?rik=5l29y7G8trIggg&riu=http%3a%2f%2fi3.img.969g.com%2fdown%2fimgx2014%2f02%2f08%2f289_093214_13ee6.jpg&ehk=Dz0E1RuS%2fO0MM4sqy3TBm9fhMKtoEti9THnsNH%2buZY0%3d&risl=&pid=ImgRaw&r=0"
response = requests.get(url) # response 当前仅仅是一个响应对象
with open("fengjing.jpg", mode="wb")as f:
f.write(response.content) #写入二进制数据不管是视频还是图片,都要 response.content
拓展:以爬虫的方式如何下载视频 – 以抖音视频为例:
import requests
url = "https://v3-web.douyinvod.com/7a7877efa760fdd53fa0c06111e57279/6568b2c2/video/tos/cn/tos-cn-ve-15c001-alinc2/o8Ey1n5mFAMNOeHhgIfGgpCzGN6AQZMhAABEBE/?a=6383&ch=26&cr=3&dr=0&lr=all&cd=0%7C0%7C0%7C3&cv=1&br=848&bt=848&cs=0&ds=6&ft=GN7rKGVVywpuRFo8Cmo~xj7ScoAp2b-6EvrK_as1d2o0g3&mime_type=video_mp4&qs=12&rc=O2gzNWlnPGVpO2gzZTpnaUBpMzNzaGc6ZjZzbjMzNGkzM0AzXmBfMF4yNV4xYDY0NV8uYSMwLWgvcjQwbS1gLS1kLS9zcw%3D%3D&btag=e00008000&dy_q=1701356714&feature_id=46a7bb47b4fd1280f3d3825bf2b29388&l=20231130230514D28ECE4FCCD8A828D414"
response = requests.get(url) # response 当前仅仅是一个响应对象
with open("douyin.mp4", mode="wb")as f:
f.write(response.content) #写入二进制数据不管是视频还是图片,都要 response.content
注意: 并不是所有的视频和图片都可以这样去爬取,有些图片和视频是加密的,url
并不会这么轻易的找到