本地正常运行的野火边界数据下载脚本在EC2上触发ConnectionResetError的可行解决方案咨询
本地正常运行的野火边界数据下载脚本在EC2上触发ConnectionResetError的可行解决方案咨询
我有一段在本地运行完全正常的野火边界数据下载脚本,用来从ESRI的服务获取野火边界GeoJSON数据,代码如下:
import requests import os from datetime import datetime # Step 1: Define URL and parameters url = "https://services3.arcgis.com/T4QMspbfLg3qTGWY/arcgis/rest/services/WFIGS_Interagency_Perimeters_Current/FeatureServer/0/query" params = { "where": "1=1", "outFields": "*", "f": "geojson", "outSR": "4326", "resultRecordCount": 2000 } # Step 2: Create folder to store files output_folder = "wildfire_polygons" os.makedirs(output_folder, exist_ok=True) # Step 3: Generate dated filename today_str = datetime.today().strftime("%Y-%m-%d") output_filename = f"fire_perimeters_{today_str}.geojson" output_path = os.path.join(output_folder, output_filename) # Step 4: Download and save only if not already downloaded if not os.path.exists(output_path): print(f"📥 Downloading fire perimeter data for {today_str}...") response = requests.get(url, params=params) response.raise_for_status() with open(output_path, 'w', encoding='utf-8') as f: f.write(response.text) print(f"✅ Saved to {output_path}") else: print(f"📂 File already exists for today: {output_path}")
但是当我在EC2实例上运行这段脚本时,却遇到了如下连接错误:
ConnectionError: ('Connection aborted.', ConnectionResetError(104, 'Connection reset by peer'))
我知道这大概率是ESRI的IP拦截机制导致的,之前看到过切换IP的建议,但这个方案对我来说不可行。想请教大家有没有其他可行的解决办法?目前我只能手动从对应的ESRI数据集下载数据,但希望能恢复自动化的方式。
可行的解决方案建议
1. 模拟浏览器请求头,避免被识别为爬虫
ESRI的服务器通常会对非浏览器的请求进行拦截,你可以给requests.get添加标准的浏览器请求头,伪装成正常的用户访问:
# 在请求前添加浏览器User-Agent headers = { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36' } # 把headers参数传入get请求 response = requests.get(url, params=params, headers=headers)
建议多准备几个不同设备的User-Agent字符串,定期切换使用,进一步降低被拦截的概率。
2. 添加智能重试机制,应对临时限流/网络波动
连接重置有时候是服务器临时限流或者网络波动导致的偶发问题,添加自动重试逻辑可以有效应对这种情况。你可以用requests的会话和重试适配器来实现:
import requests from requests.adapters import HTTPAdapter from urllib3.util.retry import Retry # 构建带重试的会话 session = requests.Session() retry_strategy = Retry( total=3, # 最大重试次数 backoff_factor=1, # 重试间隔时间(1s, 2s, 4s...) status_forcelist=[429, 500, 502, 503, 504] # 需要重试的状态码 ) adapter = HTTPAdapter(max_retries=retry_strategy) session.mount('https://', adapter) session.mount('http://', adapter) # 用session.get替代原有的requests.get response = session.get(url, params=params, headers=headers)
渐进式的重试间隔可以避免频繁请求触发更严格的拦截规则。
3. 检查EC2网络配置,确保出站访问正常
虽然你能触发连接重置说明基本网络是通的,但还是建议检查下EC2的安全组和NACL配置:
- 确认安全组的出站规则允许访问HTTPS(443端口)
- 如果EC2在私有子网,检查NAT网关是否正常工作,有没有限制出站流量
- 可以尝试在EC2上用
curl测试目标URL,看是否能正常返回内容:
curl -v "https://services3.arcgis.com/T4QMspbfLg3qTGWY/arcgis/rest/services/WFIGS_Interagency_Perimeters_Current/FeatureServer/0/query?where=1%3D1&outFields=*&f=geojson&outSR=4326&resultRecordCount=2000"
4. 申请ESRI官方授权访问
如果你的自动化需求是合法的、非大规模爬取的场景,可以尝试联系ESRI申请官方的API访问权限。官方授权后通常会提供稳定的访问通道,从根源上解决拦截问题。
5. (可选)使用代理服务绕过IP拦截
如果你的业务场景允许使用代理,可以配置代理服务器来切换请求的源IP。比如使用自己搭建的代理池或者可靠的商用代理服务,在请求中添加代理参数:
proxies = { 'https': 'https://your-proxy-address:port' } response = requests.get(url, params=params, headers=headers, proxies=proxies)
注意公开代理大多不稳定,建议选择有信誉的商用代理服务。
内容来源于stack exchange
相关产品推荐
相关产品推荐

