当前位置: 首页 > news >正文

AERONET 多源数据批量抓取:Python + Selenium 实战与 CURL/WGET 高效替代方案

1. AERONET数据抓取的核心挑战

做大气污染研究的朋友应该都深有体会,AERONET这个宝藏数据库虽然数据质量高,但每次手动下载数据简直能让人崩溃。我去年做京津冀地区十年气溶胶分析时,需要下载37个站点不同年份的AOD、SDA、FMF等数据,手动操作整整花了两周时间,期间还因为网络波动导致多次中断重来。

AERONET数据获取主要面临三个痛点:

  • 动态参数依赖:下载链接需要拼接十多个参数,包括站点名、时间范围、数据类型等,手动构造极易出错
  • 反爬机制:直接访问数据文件URL会返回404,必须先在网页完成查询操作生成临时令牌
  • 数据分散:不同产品(AOD/SDA/TOT)分布在独立子系统,统一采集需要处理多个接口

实测发现,单纯用Requests库直接访问会触发反爬,而完全依赖Selenium又太慢。后来我摸索出一套混合方案:用Selenium处理动态令牌,用CURL进行批量下载,速度比纯浏览器方案快8倍。下面具体说说这两种方案的实现细节和优化技巧。

2. Selenium自动化方案全解析

2.1 环境配置与核心组件

建议使用Python 3.8+搭配最新版ChromeDriver,这里有个坑我踩过:不同版本的WebDriver对XPath解析有差异,会导致元素定位失败。我的配置清单:

# requirements.txt selenium==4.1.0 webdriver-manager==3.5.3 pandas>=1.3.0

初始化浏览器实例时务必添加这些参数,能显著提升稳定性:

from selenium.webdriver.chrome.options import Options chrome_options = Options() chrome_options.add_argument("--headless") chrome_options.add_argument("--disable-gpu") chrome_options.add_argument("--window-size=1920x1080") chrome_options.add_argument("--log-level=3") driver = webdriver.Chrome(options=chrome_options)

2.2 站点列表获取实战

AERONET官网的地图界面其实暗藏玄机。通过分析网络请求,我发现这个技巧:先访问https://aeronet.gsfc.nasa.gov/aeronet_locations.txt 可以直接获取所有站点的经纬度信息,比解析HTML高效得多。结合BeautifulSoup提取站点详情页URL的完整代码:

def get_station_metadata(): base_url = "https://aeronet.gsfc.nasa.gov/cgi-bin/type_one_station_op_v3" resp = requests.get(base_url) soup = BeautifulSoup(resp.text, 'html.parser') stations = [] for tr in soup.select('tr[bgcolor="#CCCCCC"], tr[bgcolor="#FFFFFF"]'): tds = tr.find_all('td') if len(tds) < 5: continue station = { 'name': tds[0].text.strip(), 'url': tds[0].find('a')['href'], 'lat': float(tds[1].text), 'lon': float(tds[2].text), 'elev': float(tds[3].text), 'active': tds[4].text.strip() == 'Active' } stations.append(station) return pd.DataFrame(stations)

2.3 动态令牌获取技巧

AERONET的防直连机制非常特殊,必须先在页面执行这三个步骤:

  1. 选择年份范围(触发AJAX请求)
  2. 勾选需要的数据类型(AOD/SDA等)
  3. 点击Submit按钮生成临时令牌

关键代码实现:

def generate_download_token(driver, year_range, data_types): # 设置时间范围 select1 = Select(driver.find_element(By.ID, "Year1")) select1.select_by_value(year_range[0]) select2 = Select(driver.find_element(By.ID, "Year2")) select2.select_by_value(year_range[1]) # 勾选数据类型 for dtype in data_types: checkbox = driver.find_element(By.NAME, dtype) if not checkbox.is_selected(): checkbox.click() # 提交查询 submit = driver.find_element(By.NAME, "Submit") submit.click() # 等待令牌生成(关键!) WebDriverWait(driver, 30).until( EC.presence_of_element_located((By.PARTIAL_LINK_TEXT, "Download")) ) return driver.current_url

3. CURL/WGET高效方案详解

3.1 链接构造的玄机

通过抓包分析,我发现AERONET的下载API遵循固定格式:

https://aeronet.gsfc.nasa.gov/cgi-bin/print_web_data_v3? site={站点}&year={开始年}&month={开始月}&day={开始日} &year2={结束年}&month2={结束月}&day2={结束日} &{数据类型}=1&AVG={时间分辨率}

参数说明表:

参数必选示例值说明
siteBeijing站点ID(区分大小写)
AVG1010=原始数据,20=日均值
AOD20可选11表示需要该数据类型
hour8起始小时(0-23)
lunar_merge00=不含月数据,1=包含

3.2 批量下载性能对比

测试100个AOD20数据文件下载(单位:秒):

方法首次运行缓存后稳定性
Selenium382355
CURL4729
WGET5231
混合模式5833

混合模式实现逻辑:

# 先用Selenium获取令牌 python get_token.py --site Beijing --year 2020 > token.txt # 使用令牌批量下载 while read url; do curl -s -k -o "data/$(date +%s).csv" "$url" & if (( $(jobs | wc -l) >= 4 )); then wait -n fi done < token.txt

4. 混合策略进阶技巧

4.1 智能路由方案

根据网络环境自动选择最优方案:

def download_strategy_selector(site, years): if is_campus_network(): # 教育网走CURL return curl_download(prepare_curl_params(site, years)) else: # 其他网络走Selenium with ChromeDriver() as driver: token = get_selenium_token(driver, site, years) return threaded_download(token)

4.2 错误处理机制

针对常见问题的应对策略:

  1. 403 Forbidden:更换User-Agent,添加随机延迟
  2. 404 Not Found:重新获取令牌,检查参数格式
  3. Timeout:指数退避重试(最多3次)

增强版下载函数:

def robust_download(url, retry=3): for i in range(retry): try: with requests.Session() as s: s.headers.update({'User-Agent': get_random_user_agent()}) resp = s.get(url, timeout=30) resp.raise_for_status() return resp.content except Exception as e: if i == retry - 1: raise time.sleep(2 ** i + random.random())

5. 实战案例:长三角地区数据采集

最近帮某研究所搭建的自动化流程,核心配置:

# config.yaml regions: - name: Yangtze_Delta bbox: [30.0, 119.0, 32.5, 122.0] years: [2015-2022] data_types: [AOD20, SDA20, FMF] strategy: hybrid output_dir: ./data/YRD

执行效果:

  • 自动识别区域内12个活跃站点
  • 按年分目录存储各站点数据
  • 失败任务自动重试并记录日志
  • 日均数据更新耗时约7分钟

关键优化点:

  1. 使用Spatialite进行地理范围筛选
  2. 采用Zstandard压缩存储原始数据
  3. 集成Prometheus监控下载质量

这个方案已经稳定运行6个月,累计下载数据文件超过1.2TB。最大的收获是:一定要为每个下载任务添加完整的元数据注释,否则三个月后根本记不清某个数据文件的具体参数。我现在每个CSV文件头都自动写入这样的信息:

# Site: Shanghai # Period: 2020-01-01 to 2020-12-31 # DataType: AOD Level 2.0 # GeneratedAt: 2023-08-15T14:22:18Z # Checksum: sha256:9f86d08...
http://www.jsqmd.com/news/660970/

相关文章:

  • FigmaCN终极指南:3分钟实现Figma完美汉化,让设计更专注
  • 2026靠谱的车改品牌推荐,深入聊聊360全景武汉折扣仓中小林子车改 - 工业品牌热点
  • 亚秒级启动的微型虚拟机,打包成单文件随处运行
  • Notepad--:跨平台文本编辑器的终极选择,解决多系统编码难题
  • 终极指南:如何用免费开源的LibreCAD轻松完成专业2D绘图设计
  • 3D城市重建新突破:WHU航空数据集+RedNet实战指南(附开源地址)
  • Akagi:如何用AI智能助手提升你的雀魂麻将水平
  • 2026靠谱的工业水性涂料制造企业推荐,选购指南助你选对厂家 - 工业推荐榜
  • 在电脑上畅玩Switch游戏:Ryujinx模拟器完整使用指南
  • 别再被OpenCV的calibrateHandEye搞晕了!Eye-in-Hand与Eye-to-Hand手眼标定实战详解(附完整C++/Halcon代码)
  • 智能车竞赛备赛:手把手教你用AD21复刻英飞凌TC264核心板(附开源PCB文件)
  • 怎么一句话写尽遗憾?
  • Kaggle心脏病预测实战:用Python从EDA到模型部署的完整流程(附代码避坑点)
  • 从DSSM到美团双塔:聊聊推荐系统召回阶段那些‘负样本’的坑与实战经验
  • 口碑好的专升本机构探讨,飞扬专升本学员评价分享与实力评估 - mypinpai
  • 手把手教你用Python脚本批量下载与转换香港CORS的RINEX数据(附Matlab工具链接)
  • Anthropic说Opus 4.7工具错误降了2/3,我拿30个MCP工具实测了一下
  • 避坑指南:处理Tusimple数据集时,为什么你的generate_tusimple_dataset.py脚本‘卡住’了?
  • 开箱即用!音频像素工坊快速部署教程,打造你的专属音频处理工具箱
  • STM32 CANopenNode实战指南:如何在5步内构建工业级CANopen从站
  • 性价比高的木质防火门厂家怎么选择,深度剖析优质源头厂家 - 工业品网
  • 在Ubuntu 22.04上,用Picovoice离线语音助手控制智能家居(从唤醒词到执行命令全流程)
  • Rust Trait 对象的内存布局
  • MATLAB/Simulink 2024A实战:手把手教你搭建PMSM无磁链环DTC仿真模型(附源码)
  • Beaver Notes终极指南:打造本地优先的高效隐私笔记系统
  • 从SRCNN到ESPCN:亚像素卷积如何重塑实时超分效率
  • 别再只跑个模型了!用R语言因子分析挖掘省份消费数据里的隐藏故事
  • 2026年好用的酒店厨房装修公司推荐,实力强售后有保障 - 工业设备
  • 终极解决方案:3分钟破解城通网盘限速,免费获取满速下载!
  • Winhance中文版:3大核心功能彻底解决Windows系统优化难题