urllib简介与urllib.parse的使用
urllib 是Python自带的标准库中用于网络请求的库,无需安装,直接引用即可。
通常用于爬虫开发,API(应用程序编程接口)数据获取和测试
urllib库的4大模块
urllib.request 用于打开和读取url
urllib.error 包含提出的例外(异常)urllib.request
urllib.parse 用于解析url
urllib.robotparser 用于解析robots.txt文件
import urllib.request
url = 'https://www.runoob.com/'
#发送请求
resp = urllib.request.urlopen(url)
#decode将byte类型转成str类型
html = resp.read().decode('utf-8')
print(html)
urllib.request发送get与post请求
urllib.request库
模拟浏览器发起一个HTTP请求,并获取请求响应结果
urllib.request.urlopen的语法格式
urlopen
参数说明
url:url参数是str类型的地址,也就是要访问的URL
data:默认值为None,urllib判断参数data是否为none从而区分请求方式。
参数data为None,则代表请求方式为get,反之请求方式为post,发送post请求。
参数data以字典形式存储数据,并将参数data由字典类型转换成字节类型才能完成post请求
urlopen函数返回的结果是一个 http.client.HTTPResponse对象
import urllib.request
import urllib.parse
url = 'https://juejin.cn/passport/web/user/login/?account_sdk_source=web'
data = {
'username': 'admin',
'password': '@Test123$%^',
'captcha': '1',
'key': '1650535293946'
}
#发送请求
resp = urllib.request.urlopen(url, data=bytes(urllib.parse.urlencode(data), encoding='utf-8'))
html = resp.read().decode('utf-8')
print(html)
构造Request对象发送请求
Request
如果在请求中需要加入headers(请求头)
指定请求方式等信息,那么就可以利用更加大的Request来构建一个请求
语法
urllib.request.Request(url, data=None,headers={},method=None)
案例:爬取豆瓣网
如果直接用 urlopen
urllib.request.Request(url, data=None,headers={},method=None)
import urllib.request
url = 'https://movie.douban.com/'
resp = urllib.request.urlopen(url)
print(resp)
报错 418 发送请求遇到服务器端反爬虫,服务器拒绝响应数据
urllib.error.HTTPError: HTTP Error 418:
为了应对这种简单的反爬方式,添加一个请求头,伪装成浏览
修改代码如下:
1.构建请求对象
2.使用urlopen打开请求
3.从响应结果中读取数据
import urllib.request
url = 'https://movie.douban.com/'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36'}
#构建请求对象
req = urllib.request.Request(url, headers=headers)
#使用urlopen打开请求
resp = urllib.request.urlopen(req)
#从响应结果中读取数据
html = resp.read().decode('utf-8')
print(html)
urlopen()方法的源代码
查看源码,发现是通过一个 build_opener() 方法创建了一个_opener
global _opener
if cafile or capath or cadefault:
import warnings
warnings.warn("cafile, capath and cadefault are deprecated, use a "
"custom context instead.", DeprecationWarning, 2)
if context is not None:
raise ValueError(
"You can't pass both context and any of cafile, capath, and "
"cadefault"
)
if not _have_ssl:
raise ValueError('SSL support not available')
context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH,
cafile=cafile,
capath=capath)
https_handler = HTTPSHandler(context=context)
opener = build_opener(https_handler)
elif context:
https_handler = HTTPSHandler(context=context)
opener = build_opener(https_handler)
elif _opener is None:
_opener = opener = build_opener()
else:
opener = _opener
return opener.open(url, data, timeout)
构建自己的opener发送请求
import urllib.request
url = 'https://www.baidu.com/'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36'}
#构建请求对象
req = urllib.request.Request(url, headers=headers)
#获取opener对象
opener = urllib.request.build_opener()
resp = opener.open(req)
print(resp.read().decode())
IP代理
为什么需要使用IP代理
假如一个网站它会检测某一段时间某个IP的访问次数,
如果访问次数过多,它会禁止你的访问。
所以,你可以设置一些代理服务器来帮助你做工作,
每隔一段时间换一个代理。
IP代理的分类
透明代理:
目标网站,知道你使用了代理,并且知道你的源IP地址,
这种代理显然不符合我们这里使用代理的初衷
匿名代理:
匿名程序比较低,也就是网站知道你使用了代理,但是并不知道你的源IP地址
高匿代理:
这是最保险的方式,目录网站既不知道你使用了代理,更不值得你的源IP
如何使用IP代理
from urllib.request import build_opener
from urllib.request import ProxyHandler
proxy = ProxyHandler({'http':'106.54.128.253:999'})
opener = build_opener(proxy);
# url = 'https://www.baidu.com/'
url = 'https://smallpdf.com/cn/'
resp = opener.open(url)
print(resp.read().decode('utf-8'))
IP代理,就是为了防止反爬,所使用的。
解析与异常处理
异常处理主要用到两大类
urllib.error.URLError
用于捕获urllib.request产生的异常,使用reason属性返回错误原因
urllib.error.HTTPError
用于处理HTTP与HTTPS请求的错误,
它有三个属性
code 请求返回的状态码
reason 返回错误的原因
headers 请求返回的响应头信息