目标是爬取DB电影分类排行榜的前n页,由用户输入页数
一、urllib 异常
在爬虫过程中我们有可能会遇到异常,urllib库中有个error模块,其中有两个较为重要的异常,分别是HTTPError和URLError
- HTTPError是URLError的子类,因为http协议就是url的组成部分之一
- URLError造成原因:本地网络未连接, 服务器不存在, 连接不到特点的服务器
try/except异常捕获
使用try/except来捕捉异常
检测try语句块中的错误,从而让except语句捕获异常信息并且处理,当然如果不想在异常发生使结束程序,可以只用try来捕
import urllib.request
import urllib.error
url = 'https://www.hahahagou.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 "
}
try:
request = urllib.request.Request(url=url, headers=headers)
res = urllib.request.urlopen(request)
content = res.read.decode('utf-8')
print(content)
except urllib.error.HTTPError:
print('系统正在维护。。。')
except urllib.error.URLError:
print('系统还是正在维护。。。')
二、需要先登录的网页请求
例如我们想要下载WeiBo个人资料的页面源码,用之前同样地方式爬取会发现报错,报的是编码方式错误。 原因是想获取个人资料必定会先跳转到登录界面,其他的好多网站也是如此,登录界面和个人资料界面的编码方式不同,所以会导致此错误。
解决方案是利用登陆后的Cookie,加入到请求头中,模拟用户已经登录 在所有的请求头信息中心,最重要的两个就是上图的cookie(里面包含着用户登录的信息,有时候是动态改变的,更难处理)和referer(防盗链:判断当前路径是不是由上一个路径转过来的,一般是图片防盗链)。其他信息很多可有可无。
三、handler处理器的基本使用
Handler处理器可以定制更高级的请求头,我们需要其完成更复杂的业务逻辑,例如动态cookie和代理。其实就是替换了之前的urllib.request.urlopen(requese)
- 获取handler对象
- 获取opener对象
- 调用open方法
完整代码如下,还是以下载百度源码为例
import urllib.request
import urllib.error
url = 'https://www.baidu.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 "
}
request = urllib.request.Request(url=url, headers=headers)
handler = urllib.request.HTTPHandler()
opener = urllib.request.build_opener(handler)
response = opener.open(request)
content = response.read().decode('utf-8')
print(content)
四、代理服务器
- 可以突破自身IP访问限制,访问国外站点等
- 可以访问一些单位或团体的内部资源
- 提高访问速度
- 隐藏真实IP
使用代码配置代理的步骤
- 创建Request对象
- 创建ProxyHandler对象
- 用handler对象创建opener对象
- 使用opener.open函数发送请求
proxies = {
'http': '183.247.152.98:53281'
}
handler = urllib.request.ProxyHandler(proxies=proxies)
opener = urllib.request.build_opener(handler)
response = opener.open(request)
五、代理池
每次请求从代理池中随机选择代理IP,避免重复使用同一IP被封
import random
proxies_pool = {
{'http': 'IP1'},
{'http': 'IP2'}
}
proxies = random.choice(proxies_pool)
六、完整代码
以查阅IP地址为例,如果代理池中是正确的IP地址,打开下载的html文件就可以查到代理IP的地址。
import urllib.request
import urllib.error
import random
url = 'http://www.baidu.com/s?wd=ip'
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 "
}
proxies_pool = {
{'http': 'IP1'},
{'http': 'IP2'}
}
request = urllib.request.Request(url=url, headers=headers)
proxies = random.choice(proxies_pool)
handler = urllib.request.ProxyHandler(proxies=proxies)
opener = urllib.request.build_opener(handler)
response = opener.open(request)
content = response.read().decode('utf-8')
with open('daili.html', 'w', encoding='utf-8') as f:
f.write(content)
总结
- 用try,except语句可以捕获URL异常,HTTPError是URLError的子类
- cookie中包含了登录信息,加到请求头中可以模拟登录
- Handler处理器可以定制更高级的请求头
- 使用Handler处理器可以使用代理IP,代理池可以避免重复使用同一代理IP
|