Azure Function执行GET请求返回403状态码的问题咨询及解决建议
问题分析与解决方案
可能的原因
- IP地址被目标网站拦截:Azure Function的出站IP属于云服务商公共IP池,这类IP常被爬虫、自动化工具使用,很多网站会将云IP段加入黑名单或进行严格限制;而本地机器的民用IP不在目标网站的拦截范围内。
- TLS/SSL版本不兼容:本地Python环境与Azure Function运行环境中,
requests依赖的SSL库版本可能存在差异。部分网站仅支持特定版本的TLS协议(如TLS 1.2+),若Azure环境的SSL库默认版本不符合要求,就会被服务器拒绝。 - CDN/反爬机制的额外检测:目标网站可能使用了Cloudflare这类CDN服务,除了检查请求头,还会通过IP归属、请求频率、环境特征(如是否为服务器端自动化环境)等维度识别自动化请求,Azure Function的运行环境容易触发这类检测。
解决方案
1. 规避IP拦截
- 使用Azure Function的专用出站IP:配置Azure Function的VNet集成,分配专用的出站IP,降低被拦截的概率。
- 配置自定义代理:通过第三方代理服务(如自建VPS代理)转发请求,让请求从非云IP发出。修改代码示例:
import requests def send_request(url, headers): proxies = { 'http': 'http://your-proxy-ip:port', 'https': 'https://your-proxy-ip:port' } response = requests.get(url, allow_redirects=True, headers=headers, timeout=30, proxies=proxies) return response.status_code
2. 指定TLS版本
强制requests使用符合目标网站要求的TLS版本,比如TLS 1.2或1.3,通过ssl模块配置:
import requests import ssl from requests.adapters import HTTPAdapter from urllib3.poolmanager import PoolManager class TLSAdapter(HTTPAdapter): def init_poolmanager(self, connections, maxsize, block=False): self.poolmanager = PoolManager( num_pools=connections, maxsize=maxsize, block=block, ssl_version=ssl.PROTOCOL_TLSv1_2 # 可替换为ssl.PROTOCOL_TLSv1_3 ) def send_request(url, headers): session = requests.Session() session.mount('https://', TLSAdapter()) response = session.get(url, allow_redirects=True, headers=headers, timeout=30) return response.status_code
3. 优化请求模拟,绕过反爬检测
即使请求头看似一致,也可以补充更多浏览器特征,模拟真实用户请求:
- 完善请求头:添加
Accept-Encoding、Accept-Language、Referer等字段,示例:
headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate, br', 'Referer': 'https://nationworldnews.com/', 'DNT': '1', 'Connection': 'keep-alive', 'Upgrade-Insecure-Requests': '1' }
- 模拟会话行为:先请求目标网站主页获取Cookie,再请求目标URL,保持会话一致性:
def send_request(url, headers): session = requests.Session() # 先访问主页获取会话Cookie session.get('https://nationworldnews.com/', headers=headers, timeout=30) # 再请求目标URL response = session.get(url, allow_redirects=True, headers=headers, timeout=30) return response.status_code
内容的提问来源于stack exchange,提问作者Coder_H
相关产品推荐
相关产品推荐

