1、opener模块
之前我们用到过urlopen
,它是一个特殊的opener
(urlopen底层是基于opener实现),但是urlopen()方法不支持代理、cookie等高级功能,所以这些场景我们还是需要使用opener直接模块,这里需要先引入build_opener
模块
from urllib.request import Request, build_opener
from fake_useragent import UserAgent
# 1.爬取站点访问地址
url = "http://www.baidu.com/"
# 2.随机设置请求头信息
headers = {
"User-Agent": UserAgent().chrome
}
# 3.封装到Request对象中
req = Request(url, headers=headers)
# 4.使用opener发送请求并打印返回值
opener = build_opener()
print(opener.open(req).read().decode())
2、proxy代理
做爬虫代理是必不可少的,因为可以降低被封的风险,通常可以分为以下3类:
类别 | 描述 |
---|---|
透明代理 | 目标网站知道爬虫使用了代理,并且知道爬虫的源IP地址 |
匿名代理 | 目标网站知道爬虫使用了代理,但不知道爬虫的源IP地址 |
高匿代理 | 目标网站不知道爬虫使用了代理,也不知道源IP地址(推荐) |
使用代理需要引入ProxyHandler
,它有加密和不加密两种方式,加密格式:ProxyHandler({"http": "name:pass@ip:port"})
,不加密格式:ProxyHandler({"http": "ip:port"})
,下面的示例中,我使用了一个不加密的高匿代理
from urllib.request import Request, build_opener, ProxyHandler
from fake_useragent import UserAgent
# 1.爬取站点访问地址
url = "http://www.baidu.com/"
# 2.随机设置请求头信息
headers = {
"User-Agent": UserAgent().random
}
# 3.封装到Request对象中
req = Request(url, headers=headers)
# 4.设置代理
# handler = ProxyHandler({"http": "ip:port"})
# handler = ProxyHandler({"http": "name:pass@ip:port"})
handler = ProxyHandler({"http": "223.241.2.24:4216"}) # 高匿代理
# 4.使用opener发送请求并打印返回值
opener = build_opener(handler)
print(opener.open(req).read().decode())
3、cookie模块
3.1、模拟手动登录
cookie
是用来保存登录会话的,比如我们登录某个网站后,在浏览器控制台可以找到对应的cookie值,然后放到请求头headers中,这样就可以访问登录后的接口和页面了。
# 1.爬取站点访问地址
url = "https://www.baidu.com/"
# 2.随机设置请求头信息
headers = {
"User-Agent": UserAgent().chrome,
"Cookie":"UM_distinctid=171480584944b-09ee7451329b14-c343162-144000-1714805849524d; 53gid2=11444274951007; 53revisit=1586051254001; _ga=GA1.2.1100139484.1586051282; user=a%3A2%3A%7Bs%3A2%3A%2d%22%3i%3A36460%3Bs%3A3A%22phone%23Bs%3A11%32215815500941%%3B%7D; token=3CA77E1B0EDEFDDD7D555BD233184; CNZZDATA1273229192=1716369174-1586050996-%7C1592566707; PHPSESSID=l3f1ell71n45ts2v79ohoed6g1; huangvip=yes"
}
# 3.封装到Request对象中
req = Request(url, headers=headers)
# 4.使用opener发送请求并打印返回值
print(urlopen(req).read().decode())
3.2、模拟自动登录
需要引入HTTPCookieProcessor
处理器,这样就可以自动获取cookie值,不用手动那么麻烦
from urllib.request import Request, build_opener, HTTPCookieProcessor
from fake_useragent import UserAgent
from urllib.parse import urlencode
# 1.爬取站点访问地址
url = "https://www.baidu.com/"
form_data = {
'name': 'abcdef123456',
'password': '123456'
}
# 2.随机设置请求头信息
headers = {
"User-Agent": UserAgent().random,
}
# 3.封装到Request对象中
req = Request(url, headers=headers, data=urlencode(form_data).encode())
# 4.设置cookie处理器
handler = HTTPCookieProcessor()
# 5.使用opener发送请求并打印返回值
opener = build_opener(handler)
print(opener.open(req).read().decode())
3.3、cookie保存到本地
如果需要将cookie保存到本地,则需要引入MozillaCookieJar
模块,这样get一次cookie后,就可以多次使用,同时也支持多个爬虫共享一个cookie值
from urllib.request import Request, build_opener, HTTPCookieProcessor
from fake_useragent import UserAgent
from urllib.parse import urlencode
from http.cookiejar import MozillaCookieJar
# 获取cookie,并保存到本地
def get_cookie():
url = "https://www.baidu.com/"
form_data = {
'name': 'abcdef123456',
'password': '123456'
}
# 2.随机设置请求头信息
headers = {
"User-Agent": UserAgent().random,
}
# 3.封装到Request对象中
req = Request(url, headers=headers, data=urlencode(form_data).encode())
cookijar = MozillaCookieJar()
handler = HTTPCookieProcessor(cookijar)
opener = build_opener(handler)
opener.open(req).read().decode()
cookijar.save('cookie.txt', ignore_discard=True, ignore_expires=True)
# 从本地读取cookie后再次请求
def use_cookie():
url = "https://www.baidu.com/"
headers = {
"User-Agent": UserAgent().random
}
req = Request(url, headers=headers)
cookijar = MozillaCookieJar()
cookijar.load('cookie.txt', ignore_discard=True, ignore_expires=True)
handler = HTTPCookieProcessor(cookijar)
opener = build_opener(handler)
print(opener.open(req).read().decode())
if __name__ == '__main__':
# get_cookie()
use_cookie()
4、URLError模块
URLError
是异常捕获模块,可以帮助我们处理爬虫执行过程中遇到的错误
from urllib.request import Request, urlopen
from fake_useragent import UserAgent
from urllib.error import URLError
# 1.爬取站点访问地址
url = "https://www.baidsadu.com/"
# 2.随机设置请求头信息
headers = {
"User-Agent": UserAgent().random,
}
# 3.封装到Request对象中
req = Request(url, headers=headers)
# 4.异常捕捉
try:
resp = urlopen(req)
print(resp.read().decode())
except URLError as e:
if e.args is ():
print(e.code)
else:
print(e.args[0])
print('执行完毕')