Python优化requests请求:仅校验状态码不下载完整图片资源
问题优化方案
你当前代码效率低的核心原因是:默认调用requests.get()时,requests会自动下载完整响应体后才返回结果,遇到大体积图片会消耗大量带宽和等待时间。你可以通过以下两种方式实现仅校验状态码、不下载图片内容的效果:
- 优先使用
HEAD请求
HTTP协议原生支持HEAD请求方法,服务器收到这类请求时只会返回响应状态码和响应头,完全不会返回图片等实体内容,是资源存活校验场景下最高效的方案。
注意:少部分站点会禁用HEAD方法,或对HEAD请求返回与GET请求不一致的状态码,遇到这类场景切换到第二种方案即可。 - 备选:GET请求开启
stream=True
给GET请求传入stream=True参数后,requests只会先拉取响应头、完成状态码解析,不会立刻下载完整响应体,只有你主动访问req.content、req.text等属性或迭代响应内容时,才会开始拉取实体数据。判断完状态码后主动调用req.close()释放连接即可,不会产生图片内容的下载流量。
修正后的可运行代码
注意你原有代码存在缩进错误:else块错误缩进在with open代码块内部,会触发语法异常,以下是修正优化后的版本:
import requests s = requests.Session() # 配置全局超时,避免个别请求卡死整个程序 s.timeout = 15 for url in list_: try: # 优先发HEAD请求,允许自动跳转 resp = s.head(url, allow_redirects=True) # 如果HEAD请求被拒绝,改用stream模式的GET请求 if resp.status_code in (403, 404, 405): resp = s.get(url, stream=True, allow_redirects=True) # 直接关闭连接,不读取响应体 resp.close() if resp.status_code == 200: print(f'FOUND!: {url}') with open('encontrados.txt', 'a', encoding='utf-8') as f: f.write(url + '\n') except requests.exceptions.RequestException: # 捕获连接超时、DNS解析失败、连接重置等异常,直接跳过即可 pass
内容的提问来源于stack exchange,提问作者André Chrisostomo
相关产品推荐
相关产品推荐

