使用python实现drcom服务的接口
根据校园网登录界面,F12解析请求,使用python3实现3个功能:
检查登录状态
登录
注销
web_login.py
import requests
import json
import re
import sys
import logging
from urllib.parse import quote
import argparse
# 配置日志
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
# 常量定义
BASE_URL = "http://*.*.*.*"认证的网址。
AUTH = ("user", "passwd") # 路由器认证信息
# 获取 WAN IP 地址,我这里使用路由器登录的,所以需要获取路由器的wan口ip,如果直接使用电脑则不需要用这个获取。
def get_wan_ip():
url = "http://内网路由器/status_wanlink.asp"
try:
response = requests.get(url, auth=AUTH, timeout=10)
response.raise_for_status()
content = response.text
match = re.search(r"wanlink_ip4_wan\(\)\s*\{\s*return\s*'([\d\.]+)'", content)
return match.group(1) if match else "0.0.0.0"
except requests.exceptions.RequestException as e:
logging.error(f'获取 WAN IP 地址失败: {e}')
return "0.0.0.0"
# 执行请求并解析返回的 JSON 数据
def web_analyze(url):
try:
response = requests.get(url, timeout=10)
response.raise_for_status()
text = response.text
if '(' in text and ')' in text:
return json.loads(text[text.index('(') + 1:text.rindex(')')])
return json.loads(text)
except (requests.exceptions.RequestException, json.JSONDecodeError) as e:
logging.error(f'请求或解析失败: {e}')
return None
# 处理 JSON 数据
def handle_json_data(json_data):
if not json_data:
return -1 # 如果数据为空,返回 -1
result = json_data.get("result", -1)
msg = json_data.get("msg", "未知消息")
if result == 1:
logging.info(f'返回代码: {result}, 消息: {msg}')
logging.info('操作成功!')
elif result == 0:
if "已经在线" in msg:
logging.warning(f'返回代码: {result}, 消息: {msg}')
logging.warning('已经在线,请勿重复登录!')
else:
logging.error(f'操作失败,返回数据: {json_data}')
else:
logging.error(f'未知返回代码: {result}, 消息: {msg}')
logging.error('操作状态未知!')
return result # 返回 result 值
# 解析命令行参数
def parse_args():
parser = argparse.ArgumentParser(description="处理登录、注销和检查状态的脚本")
parser.add_argument("action", choices=["check", "logout", "wanip", "login"], help="操作类型")
parser.add_argument("username", nargs="?", help="用户名(仅用于登录操作)")
parser.add_argument("password", nargs="?", help="密码(仅用于登录操作)")
return parser.parse_args()
if __name__ == '__main__':
args = parse_args()
if args.action == "login" and (not args.username or not args.password):
logging.error("Error: 登录操作需要用户名和密码")
sys.exit(1)
result = -1 # 默认返回 -1
if args.action == "check":
url = f'{BASE_URL}/drcom/chkstatus?callback=dr1002&jsVersion=4.1&v=7123&lang=zh'
json_data = web_analyze(url)
if json_data:
result = json_data.get("result", -1)
logging.info(f'登录状态: {result}')
logging.info(f'IP 地址: {json_data.get("v46ip", "未知IP")}')
elif args.action == "logout":
url = f'{BASE_URL}/drcom/logout?callback=dr1006&jsVersion=4.1&v=1949&lang=zh'
json_data = web_analyze(url)
if json_data:
result = json_data.get("result", -1)
if result == 0:
logging.error(f'登录出错:{json_data.get("msga", "未知错误")}')
else:
logging.info(f'注销状态: {result}')
logging.info(f'IP 地址: {json_data.get("ss5", "未知IP")}')
elif args.action == "wanip":
wan_ip = get_wan_ip()
logging.info(f'WAN IP 地址: {wan_ip}')
result = 1 if wan_ip != "0.0.0.0" else -1 # 如果获取到 IP,返回 1;否则返回 -1
elif args.action == "login":
wan_ip = get_wan_ip()
url = (
f'{BASE_URL}:801/eportal/portal/login?callback=dr1003&login_method=1&'
f'user_account={quote(args.username)}&user_password={quote(args.password)}&'
f'wlan_user_ip={wan_ip}&wlan_user_ipv6=&wlan_user_mac=000000000000&'
f'wlan_ac_ip=&wlan_ac_name=&jsVersion=4.1.3&terminal_type=1&lang=zh-cn&v=4639&lang=zh'
) #F12 查看的post链接,直接组合
json_data = web_analyze(url)
result = handle_json_data(json_data) # 调用 handle_json_data 处理并返回 result
else:
logging.error("Error: 无效的操作类型")
sys.exit(1)
print(result) # 统一输出 result 值
上述py可以实现三个效果(我已经登录了就没有展示了)
> python .\web.py login xxxxxxxxx xxxxxxxxx # 使用账号密码登录
2025-01-08 12:26:59,384 - WARNING - 返回代码: 0, 消息: IP: 10.252.*.* 已经在线!
2025-01-08 12:26:59,385 - WARNING - 已经在线,请勿重复登录!
0
PS C:\Users\guo\Desktop\proxy> python web.py check
2025-01-08 12:26:26,853 - INFO - 登录状态: 1
2025-01-08 12:26:26,853 - INFO - IP 地址: 10.252.4.235
1
> python .\web.py logout # 注销
编写PowerShell脚本执行自动登录
# 配置路径和参数
$web_path = "D:\login\web.py" # 替换为 Python 脚本的路径
$username = "xxxxxxxxx" # 校园网的账号
$password = "xxxxxxxxx" # 校园网的密码
# 主循环
while ($true) {
try {
# 调用 Python 脚本检查登录状态
$result = & python $web_path check
Write-Host "检查结果: $result"
# 解析 Python 脚本的输出
if ($result -match "0") {
Write-Host "未登录,尝试登录..."
$login_result = & python $web_path login $username $password
Write-Host "登录结果: $login_result"
} elseif ($result -match "1") {
Write-Host "已登录,无需操作"
} else {
Write-Host "未知状态,跳过"
}
} catch {
Write-Host "发生错误: $_"
Pause
}
# 等待 1800 秒后再次检查
Start-Sleep -Seconds 1800
}
添加开机启动,实现开机自动启动。如果是linux系统也是同理。
为了防止脚本意外退出,我还设置了一个守护脚本(windows添加每小时运行一次的计划任务即可),当然也可以将上面脚本设置成计划任务。
# 配置路径和参数
$script_name = "auto_login_web.ps1" # 主脚本的名称
$ping_target = "www.baidu.com" # 外网检测的目标 IP 或域名
$ping_timeout = 1000 # Ping 超时时间(毫秒)
$max_retries = 3 # 最大重试次数
# 检测外网连通性,如果网络是好的就没必要进行启动任务。
function Test-InternetConnection {
$retry_count = 0
while ($retry_count -lt $max_retries) {
try {
# 使用 ping.exe 检测
$ping_result = ping $ping_target -n 1 -w $ping_timeout
# 输出调试信息
Write-Host "Ping 尝试 $($retry_count + 1): $ping_result"
# 如果结果包含 "TTL=",说明 Ping 成功
if ($ping_result -match "TTL=") {
return $true
}
} catch {
# 输出错误信息
Write-Host "Ping 尝试 $($retry_count + 1) 失败: $_"
}
# 增加重试次数
$retry_count++
# 等待 1 秒后重试
Start-Sleep -Seconds 1
}
# 如果 3 次都失败,返回 false
return $false
}
# 主逻辑
if (-not (Test-InternetConnection)) {
Write-Host "外网不通,正在检查主脚本是否运行..."
# 检查主脚本是否在运行
$process = Get-Process -Name powershell -ErrorAction SilentlyContinue | Where-Object {
$_.MainWindowTitle -match $script_name
}
if (-not $process) {
Write-Host "主脚本未运行,正在启动..."
Start-Process powershell -ArgumentList "-File `"$PSScriptRoot\$script_name`""
} else {
Write-Host "主脚本正在运行"
}
} else {
Write-Host "外网正常,跳过检测"
}
使用路由器脚本(我的是Padavan)实现drcom登录
#!/bin/sh
# 配置区(使用前必须修改!!!)
BASE_URL="http://your_auth_server" # 认证服务器地址
USERNAME="your_username" # 宽带账号
PASSWORD="your_password" # 宽带密码
WAN_IF="eth3" # WAN口网络接口
# 日志记录
log() {
echo "[$(date '+%m-%d %H:%M:%S')] $1"
}
# 获取WAN口IP
get_wan_ip() {
ifconfig $WAN_IF | awk -F'[ :]+' '/inet addr/ {print $4}'
}
# 简易JSON解析
parse_json() {
echo "$1" | sed -n 's/.*"'"$2"'":\([^,}]*\).*/\1/p' | tr -d '"'
}
# 状态检测
check_login() {
response=$(curl -s "$BASE_URL/drcom/chkstatus?callback=dr1002&jsVersion=4.1&v=7123&lang=zh" 2>&1)
# 检测curl是否超时
case $response in
*"timed out"*)
log "网络连接超时"
return 2
;;
*"Could not resolve host"*)
log "DNS解析失败"
return 3
;;
esac
json_data=$(echo "$response" | sed 's/^dr[0-9]*(//;s/)$//')
result=$(parse_json "$json_data" "result")
[ "$result" = "1" ] && return 0 || return 1
}
# 执行登录
do_login() {
wan_ip=$(get_wan_ip)
[ -z "$wan_ip" ] && { log "获取WAN口IP失败"; return 1; }
login_url="$BASE_URL:801/eportal/portal/login?callback=dr1003&login_method=1&user_account=$USERNAME&user_password=$PASSWORD&wlan_user_ip=$wan_ip&wlan_user_mac=000000000000&jsVersion=4.1.3&lang=zh"
response=$(curl -s "$login_url" 2>&1)
json_data=$(echo "$response" | sed 's/^dr[0-9]*(//;s/)$//')
case $(parse_json "$json_data" "result") in
"1")
log "登录成功 ➜ IP: $wan_ip"
return 0
;;
"0")
msg=$(parse_json "$json_data" "msg")
log "登录失败:${msg:-未知错误}"
return 1
;;
*)
log "服务器返回异常:$json_data"
return 1
;;
esac
}
# 主程序
main() {
# 优先获取WAN口IP
wan_ip=$(get_wan_ip)
[ -z "$wan_ip" ] && { log "获取WAN口IP失败,请检查网线连接"; exit 1; }
log "当前WAN口IP ➜ $wan_ip"
check_login
case $? in
0)
log "当前已在线 ✔"
;;
1)
log "检测到未登录,开始认证..."
do_login || exit 1
;;
2)
log "网络异常,尝试强制登录..."
do_login
;;
*)
log "系统错误,请检查网络配置"
exit 1
;;
esac
}
# 执行主程序
main
文章参考了3D_DLW 的 https://blog.csdn.net/DLW__/article/details/131642450