API调用脚本手动运行正常但Cron任务执行失败求助
我的Python脚本调用https://stat-xplore.dwp.gov.uk/webapi/rest/v1/schema接口,手动运行完全正常,但通过Cron任务执行时总是报连接超时错误:
Request failed: HTTPSConnectionPool(host='stat-xplore.dwp.gov.uk', port=445): Max retries exceeded with url: /webapi/rest/v1/schema (Caused by ConnectTimeoutError(<urllib3.connection.VerifiedHTTPSConnection object at 0j0iefhfnfj9>, 'Connection to stat-xplore.dwp.gov.uk timed out. (connect timeout=30)'))
已经尝试以下方法但问题仍未解决:
- 增加请求超时时间
- 调整环境变量设置
- 检查脚本文件权限
- 测试服务器网络连通性
我的Python脚本
#!/usr/bin/python3 import json import requests import os url = 'https://stat-xplore.dwp.gov.uk/webapi/rest/v1/schema' # Set your API key in the environment variable os.environ['APIKey'] = 'myapikey' #I have also tried this without setting environment variable #api_key='myapikey' # Get the API key from the environment variable api_key = os.environ['APIKey'] headers = {'Accept': 'application/json', 'APIKey': api_key} try: response = requests.get(url, headers=headers, timeout=30) print(response) # Process the response... except requests.RequestException as e: print("Request failed:", e)
Cron任务配置
42 18 * * * /usr/bin/python3 /home/user/bin/bash/statxplore_api.py
可能的解决方向
1. 验证Cron的网络连通性
Cron的运行环境和手动shell会话不同,可能存在DNS解析或路由问题。可以在Cron任务中先执行网络测试,把结果写入日志排查:
42 18 * * * ping -c 3 stat-xplore.dwp.gov.uk >> /home/user/cron_network.log 2>&1 && /usr/bin/python3 /home/user/bin/bash/statxplore_api.py >> /home/user/cron_script.log 2>&1
查看日志确认Cron环境能否正常解析域名并连通目标服务器。
2. 显式指定CA证书路径
部分系统中,Cron环境下的Python可能无法找到默认CA证书库,导致HTTPS连接验证失败(表现为超时)。可以在requests请求中指定系统CA证书路径:
# 替换为你的系统CA证书路径,常见路径如/etc/ssl/certs/ca-certificates.crt response = requests.get(url, headers=headers, timeout=30, verify='/etc/ssl/certs/ca-certificates.crt')
3. 给Cron加载完整环境变量
手动运行时的环境变量(如代理、PATH等)在Cron中可能缺失。可以让Cron先加载用户的bash环境再执行脚本:
42 18 * * * source /home/user/.bashrc && /usr/bin/python3 /home/user/bin/bash/statxplore_api.py >> /home/user/cron_script.log 2>&1
如果使用代理,也可以直接在脚本中显式设置:
os.environ['HTTP_PROXY'] = 'http://your-proxy:port' os.environ['HTTPS_PROXY'] = 'http://your-proxy:port'
4. 检查端口配置
错误中显示连接的是445端口,但HTTPS默认端口为443,确认脚本中的URL是否写错端口;同时检查服务器防火墙是否允许Cron进程访问目标端口。
5. 添加请求重试机制
Cron执行时可能遇到临时网络波动,给requests添加重试逻辑提升稳定性:
from requests.adapters import HTTPAdapter from urllib3.util.retry import Retry session = requests.Session() # 配置重试策略:最多重试5次,每次间隔1秒,针对5xx状态码重试 retry = Retry(total=5, backoff_factor=1, status_forcelist=[500, 502, 503, 504]) adapter = HTTPAdapter(max_retries=retry) session.mount('https://', adapter) try: response = session.get(url, headers=headers, timeout=30) print(response) except requests.RequestException as e: print("Request failed:", e)
内容的提问来源于stack exchange,提问作者Flanimal

