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

如何让Python脚本模拟浏览器通过WiFi Captive Portal认证?

解决Captive Portal拒绝Python脚本请求的问题

我尝试用Python脚本通过POST方法连接带浏览器门户(Captive Portal)的WiFi,但门户因识别出请求并非来自浏览器而拒绝。以下是我的代码:

import requests

url = 'https://xxx/portal_api.php'

# Add appropriate credentials here
payload = {
    "action": "authenticate",
    "login": "xxx@xxx.com",
    "password": "xxxx",
    "policy_accept": "false",
    "from_ajax": "true"
}

# Send a POST request with the credentials
response = requests.post(url, data=payload)

payload2 = {
    "action": "switch_language",
    "isAppleCNA_fakeclick": "false",
    "lang": "fr"
}

# Check if the connection was successful
if response.status_code == 200:
    print("Connection successful 1")
    response2 = requests.post(url, data=payload2)
    if response2.status_code == 200:
        print("Connection successful 2")
else:
    print("Connection failed")

我期望能成功连接并收到两个成功提示,但实际并未连接。用Postman测试请求时,收到如下响应:

<html>

<head>
    <title>Forbidden access</title>
</head>

<body style="text-align:center">
    <div
        style="width:80%; border:1px solid #64696C; color:#64696C; font-weight:bold; text-align:center; padding:20px; margin:auto; margin-top:20px">
        <p id="small_p" style="font-size:small;">Forbidden access</p>
        <p id="large_p" style="font-size:large;">Your current web browser cannot access this page.</p>
    </div>
</body>

</html>

解决方法

要让门户认为脚本是合法浏览器,需要模拟浏览器的请求特征,主要做以下几点:

  • 添加浏览器的User-Agent请求头
    绝大多数Captive Portal会通过User-Agent字段识别请求来源。你需要在请求中添加主流浏览器的User-Agent值,比如Chrome的标识:

    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'
    }
    
  • 使用Session保持会话Cookie
    浏览器访问门户时会自动保存并携带会话Cookie,脚本需要用requests.Session()来维护同一个会话,否则每次请求都是独立的,门户会判定为非法请求。

  • 补充其他必要请求头
    部分门户还会检查Referer(请求来源页面)、Accept等字段,你可以通过浏览器开发者工具(F12)查看真实浏览器请求的完整头信息,复制到脚本中。

修改后的完整代码示例

import requests

# 创建会话对象,自动维护Cookie
session = requests.Session()

url = 'https://xxx/portal_api.php'

# 模拟Chrome浏览器的请求头
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',
    'Referer': 'https://xxx/portal_page.html',  # 替换为门户的实际登录页面URL
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8'
}

payload = {
    "action": "authenticate",
    "login": "xxx@xxx.com",
    "password": "xxxx",
    "policy_accept": "false",
    "from_ajax": "true"
}

# 发送认证请求,携带请求头和会话
response = session.post(url, data=payload, headers=headers)

payload2 = {
    "action": "switch_language",
    "isAppleCNA_fakeclick": "false",
    "lang": "fr"
}

if response.status_code == 200:
    print("Connection successful 1")
    # 同一个会话发送第二个请求,自动携带Cookie
    response2 = session.post(url, data=payload2, headers=headers)
    if response2.status_code == 200:
        print("Connection successful 2")
else:
    print("Connection failed")
    # 打印响应内容排查问题
    print(response.text)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 05:55:04