使用Apache Airflow调用MercadoBitcoin API时遭遇403错误求助
问题分析
你的判断完全正确:MercadoBitcoin的API受Cloudflare防护,Airflow的SimpleHttpOperator默认发送的请求头缺少浏览器标识等关键信息,被Cloudflare判定为爬虫请求,从而触发1020访问拒绝错误。而你用自定义requests函数时,默认会携带更接近常规浏览器的请求头(比如User-Agent),因此能正常获取数据。
解决方案
1. 为SimpleHttpOperator添加自定义请求头
直接在Operator实例中通过headers参数设置模拟浏览器的请求头,核心是添加User-Agent字段,示例代码如下:
from airflow.providers.http.operators.http import SimpleHttpOperator get_btc_data = SimpleHttpOperator( task_id="get_btc_day_summary", http_conn_id="mercadobitcoin_conn", endpoint="api/BTC/day-summary/2022/7/10", method="GET", headers={ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36" }, response_filter=lambda response: response.json(), )
如果希望将请求头配置到Airflow的HTTP连接中(避免硬编码),可以在连接的Extra字段中添加JSON格式的配置:
{"headers": {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"}}
2. 使用PythonOperator替代SimpleHttpOperator
既然你的自定义requests函数已经能正常工作,直接将请求逻辑封装到PythonOperator中是更灵活的方案,示例代码:
from airflow.operators.python import PythonOperator import requests def fetch_btc_data(): url = "https://www.mercadobitcoin.com.br/api/BTC/day-summary/2022/7/10" headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36" } response = requests.get(url, headers=headers) response.raise_for_status() # 抛出请求错误 return response.json() get_btc_data = PythonOperator( task_id="fetch_btc_day_summary", python_callable=fetch_btc_data )
3. 检查Docker网络配置(可选)
如果添加请求头后仍然报错,可能是Airflow所在Docker容器的IP被Cloudflare列入了可疑IP段。可以尝试:
- 将Docker容器切换为主机网络模式(在
docker-compose.yml中设置network_mode: host),使用宿主机的IP发起请求 - 配置合法的HTTP代理(确保代理IP未被Cloudflare拦截),在请求中添加代理参数
内容的提问来源于stack exchange,提问作者Luis Felipe
相关产品推荐
相关产品推荐

