You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

禁用Cookie与JS的Firefox可访问URL,urllib爬取报403 Forbidden

网站检测爬虫的可能机制及解决建议

一、检测机制分析

针对你遇到的403问题,idealista.pt大概率通过以下几种方式识别爬虫:

  • 请求头完整性校验:你仅设置了User-Agent,但浏览器正常请求会附带Accept、Accept-Language、Accept-Encoding、Connection等关键头字段,网站会通过校验请求头的完整性来区分爬虫与真实浏览器。
  • SSL握手指纹差异:你使用了空的ssl.SSLContext(),这和Firefox实际使用的SSL上下文(如支持的加密套件、TLS版本、扩展信息等)差异极大,网站可通过TLS握手时的指纹信息识别爬虫工具。
  • 请求行为特征识别:urllib发起请求的模式和浏览器不同,比如缺少浏览器默认的请求前预检逻辑,或者请求数据包的结构、时序不符合人类浏览的常规特征,哪怕单次请求也可能被判定为爬虫。

二、代码修正建议

1. 补全完整请求头

直接复制Firefox请求中的所有头信息,模拟真实浏览器请求:

import urllib.request
import ssl
import gzip
from io import BytesIO

USER_AGENT_VALUE = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/111.0'
TIMEOUT = 10

def get_page(url):
    # 复制Firefox的完整请求头
    headers = {
        'User-Agent': USER_AGENT_VALUE,
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
        'Accept-Language': 'en-US,en;q=0.5',
        'Accept-Encoding': 'gzip, deflate, br',
        'Connection': 'keep-alive',
        'Upgrade-Insecure-Requests': '1',
        'TE': 'Trailers'
    }
    req = urllib.request.Request(url, headers=headers)
    
    # 使用默认SSL上下文,更接近浏览器配置
    context = ssl.create_default_context()
    response = urllib.request.urlopen(req, context=context, timeout=TIMEOUT)

    data = response.read()
    # 处理网站可能返回的gzip压缩内容
    if response.info().get('Content-Encoding') == 'gzip':
        data = gzip.GzipFile(fileobj=BytesIO(data)).read()
    html = data.decode('utf-8') 

    return html

2. 额外注意事项

如果补全请求头后仍无法访问,可尝试:

  • 降低请求频率,避免触发IP限流;
  • 使用requests库配合更贴近浏览器的SSL指纹配置;
  • 极端情况下用selenium模拟真实浏览器操作(需注意网站的反爬策略)。

内容的提问来源于stack exchange,提问作者ginjaemocoes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 20:43:10