学习爬虫的过程,写了一个敏感路径探测的脚本,在探测某一URL响应码是否为200的过程中,脚本超时了很久(大概十分钟的样子)才弹出来报错,开始了对timeout参数以及request报错的学习
- 最初的报错
核心代码如下:
response = requests.get(url, headers=headers) print(url+" 响应码:"+str(response.status_code)) if response.status_code == 200: domain.append(url)
只要响应码为200,就加入到domain这个列表中
最终在访问 /actuator/heapdump目录的时候,卡住跑不动了,大概得过了十多分钟,才给报错,报错为以下三条:
socket.timeout: timed out
urllib3.exceptions.ConnectTimeoutErro
requests.exceptions.ConnectionError
- 修改DNS
上网搜了一下,从最后一句报错得知原因可能是网络问题,需要改一下DNS地址,所以我将DNS修改为阿里的223.5.5.5
这时再跑一遍程序,跑到/actuator/heapdump目录的时候又停住了(卡住至少10分钟),但过了很久一看程序跑完了,给的响应码是200,为可以访问,说明修改DNS还是有效果的,现在问题出现在这个目录/actuator/heapdump
-
遇到大图片或文件
当我访问这个 目录时,游览器马上弹出下载文件的选项,这不挺快的嘛,为啥python跑到这这么慢呢?是因为游览器发送的包和python发送的包不一样吗?
我尝试用bp抓一下包
发送!
等了特别久终于得到了响应包,响应体也就是那个headump文件的内容,也就是说出于网络或者其他原因,导致我们用发包的方式去判断页面是否可访问,会消耗相当多的时间。所以第一反应当然是设置超时了,还好request自带timeout参数。 -
设置timeout
requests 设置超时时间有两种方式。
一种是设置单一值作为 timeout,如:
response = requests.get(url, headers=headers, timeout=10)
此时连接超时时间和读取超时时间都是10s
另一种是分别制定连接超时和读取超时的时间,如:
response = requests.get(url, headers=headers, timeout=(6.05,12.05))
这里的6.05代表连接超时时间,12.05代表读取超时时间
官方一般推荐大家把连接超时时间设置为比 3 的整数倍稍微大一点的时间,比如 3.05、6.05,具体原因请查阅文档。
简单地说,连接超时时间,就是发起请求到连接建立所花的时间,读取超时时间,连接成功开始到服务器返回响应之间等待的最大时长。
这里还要补充一点,如果不设置timeout参数的话,连接超时时间大概为21s,无默认读取超时时间,也就是说读取永远不会超时。
- timeout参数没有效果
我们先设置timeout=10(连接与读取超时都为10s)试试
还是跑到/actuator/heapdump目录的时候,卡住了,大概过了十几分钟,才给了三条报错:
socket.timeout: timed out
urllib3.exceptions.ReadTimeoutError
requests.exceptions.ConnectionError
这不就是之前的那个报错吗,而且这timeout没啥没起作用啊?
- 设置异常处理 try······except
try:
response = requests.get(url, headers=headers, timeout=10)
# print(url + i)
print(url+" 响应码:"+str(response.status_code))
if response.status_code == 200:
domain.append(url)
except requests.exceptions.ReadTimeout:
print(url+" 读取超时")
except requests.exceptions.ConnectionError:
print(url+" 连接出错")
尝试通过设置异常处理,看看到底是哪里出了问题
最终还是连接出现了问题,遇到网络问题(如:DNS 查询失败、拒绝连接等)可能会报requests.exceptions.ConnectionError 异常,比较复杂,通过异常处理直接忽略掉吧。



