基于Python异步编程的完整技术实现
前言
在移动互联网时代,各类APP的签到任务已成为用户日常操作的重要组成部分。本文将深入解析一个基于Python异步编程实现的同程旅行自动化签到脚本,从技术架构、核心算法到实际应用,为开发者提供完整的自动化脚本开发思路。
技术架构概览
核心技术栈
- 异步编程框架 :
asyncio
+httpx
- HTTP客户端 :
httpx.AsyncClient
- 环境配置管理 :
os.environ
+dotenv
- 消息推送: Bark推送 + 青龙面板notify
- 并发处理 :
asyncio.gather()
系统架构图
环境变量配置 多账号Cookie解析 异步任务调度器 账号1 - Tclx实例 账号2 - Tclx实例 账号N - Tclx实例 签到检查 任务列表获取 任务执行循环 API调用层 同程旅行API 结果汇总 推送通知 日志输出
核心技术实现
1. 异步HTTP客户端设计
python
class Tclx:
def __init__(self, cookie):
self.client = httpx.AsyncClient(
base_url="https://app.17u.cn/welfarecenter",
verify=False,
timeout=60
)
self.phone = cookie.split("#")[0]
self.apptoken = cookie.split("#")[1]
self.device = cookie.split("#")[2]
# 构建标准化请求头
self.headers = {
'accept': 'application/json, text/plain, */*',
'phone': self.phone,
'channel': '1',
'apptoken': self.apptoken,
'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 TcTravel/11.0.0 tctype/wk',
'device': self.device,
}
技术:
- 使用
httpx.AsyncClient
实现高性能异步HTTP请求 - 通过
base_url
统一管理API端点 - 动态构建请求头,支持多账号身份认证
- 合理设置超时时间,避免请求阻塞
2. 环境变量管理与配置解析
python
def get_env(env_var, separator):
"""智能环境变量解析器"""
if env_var in os.environ:
return re.split(separator, os.environ.get(env_var))
else:
try:
from dotenv import load_dotenv, find_dotenv
load_dotenv(find_dotenv())
if env_var in os.environ:
return re.split(separator, os.environ.get(env_var))
else:
fn_print(f"未找到{env_var}变量.")
return []
except ImportError:
fn_print(f"未找到{env_var}变量且无法加载dotenv.")
return []
技术特色:
- 支持系统环境变量和
.env
文件双重配置 - 自动降级处理,确保脚本在不同环境下的兼容性
- 使用正则表达式分割多账号配置
3. 异步任务调度与并发控制
python
async def main():
"""主调度器:实现多账号并发处理"""
tasks = []
for cookie in tc_cookies:
tclx = Tclx(cookie)
tasks.append(tclx.run())
# 使用asyncio.gather实现真正的并发执行
results = await asyncio.gather(*tasks)
return results
并发:
- 多账号任务并行执行,显著提升处理效率
- 避免串行等待,充分利用I/O等待时间
- 通过
asyncio.gather
统一管理异步任务生命周期
4. 重试机制
python
async def finsh_task(self, task_id):
"""任务完成提交 - 带指数退避重试"""
max_retry = 3
retry_delay = 2
for attempt in range(max_retry):
try:
response = await self.client.post(
url="/task/finish",
headers=self.headers,
json={"id": task_id}
)
data = response.json()
if data['code'] == 2200:
fn_print(f"用户【{self.phone}】 - 完成任务【{task_id}】成功!")
return True
if attempt < max_retry - 1:
fn_print(f"用户【{self.phone}】 - 重试第{attempt + 1}次...")
await asyncio.sleep(retry_delay * (attempt + 1)) # 指数退避
continue
return False
except Exception as e:
if attempt == max_retry - 1:
return False
await asyncio.sleep(retry_delay * (attempt + 1))
重试策略:
- 指数退避算法:2s → 4s → 6s
- 最大重试3次,避免无限循环
- 异常捕获与优雅降级
API接口设计分析
接口架构
接口路径 | 功能描述 | 请求方式 | 关键参数 |
---|---|---|---|
/index/signIndex |
签到状态查询 | POST | 无 |
/index/sign |
执行签到 | POST | type , day |
/task/taskList |
获取任务列表 | POST | version |
/task/start |
开始任务 | POST | taskCode |
/task/finish |
完成任务 | POST | id |
/task/receive |
领取奖励 | POST | id |
状态码设计
python
# 统一状态码处理
if data['code'] != 2200:
# 业务异常处理
return None
else:
# 正常业务逻辑
return process_data(data)
消息推送系统
Bark推送集成
python
# Bark推送配置
BARK_PUSH = os.getenv("BARK_PUSH")
CUSTOM_BARK_ICON = "Travel.png"
CUSTOM_BARK_GROUP = "同程旅行"
PUSH_SWITCH = "0" # 推送开关控制
# 环境变量覆盖机制
os.environ["BARK_ICON"] = BARK_ICON
os.environ["BARK_GROUP"] = BARK_GROUP
os.environ["PUSH_SWITCH"] = PUSH_SWITCH
推送内容
python
def generate_push_summary(self):
"""生成精简推送摘要"""
summary = f" {self.phone}\n • {self.summary_info['status']}本月签到{self.summary_info['cycle_sign_num']}天\n • 当前里程: {self.summary_info['mileage']}(+{self.summary_info['today_mileage']})"
return summary
日志系统设计
全局日志收集
python
all_print_list = []
def fn_print(*args, sep=' ', end='\n', **kwargs):
"""增强版print函数 - 支持日志收集"""
global all_print_list
output = ""
for index, arg in enumerate(args):
if index == len(args) - 1:
output += str(arg)
continue
output += str(arg) + sep
output = output + end
all_print_list.append(output)
print(*args, sep=sep, end=end, **kwargs)
日志特性:
- 双重输出:控制台实时显示 + 内存缓存
- 完整执行轨迹记录
- 支持后续日志分析和调试
业务流程自动化
完整执行流程
python
async def run(self):
"""单账号完整自动化流程"""
# 1. 初始化账号信息
self.summary_info = {
'phone': self.phone,
'status': '未签到',
'cycle_sign_num': 0,
'continuous_history': 0,
'mileage': 0,
'today_mileage': 0
}
# 2. 签到状态检查与执行
today_sign = await self.sign_in()
if not today_sign:
await self.do_sign_in()
# 3. 任务列表获取与执行
tasks = await self.get_task_list()
if tasks:
for task in tasks:
task_id = await self.perform_tasks(task['taskCode'])
if task_id:
await asyncio.sleep(task['browserTime']) # 模拟浏览时间
if await self.finsh_task(task_id):
await self.receive_reward(task_id)
# 4. 积分信息更新
await self.get_mileage_info()
# 5. 推送摘要生成
self.generate_push_summary()
return self.summary_info
性能策略
1. 异步并发
- 多账号并行处理,理论性能提升N倍(N为账号数量)
- I/O密集型任务异步化,CPU利用率最大化
2. 网络请求
- 连接复用:
httpx.AsyncClient
自动管理连接池 - 超时控制:避免长时间阻塞
- 请求头优化:减少不必要的数据传输
3. 内存管理
- 及时释放大对象引用
- 使用生成器处理大数据集
- 合理控制并发数量
错误处理与容错机制
多层异常处理
python
try:
# 业务逻辑
response = await self.client.post(url, headers=self.headers, json=payload)
data = response.json()
# 业务状态码检查
if data['code'] != 2200:
self.handle_business_error(data)
return None
return self.process_success_data(data)
except httpx.TimeoutException:
fn_print(f"请求超时: {url}")
return None
except httpx.NetworkError:
fn_print(f"网络错误: {url}")
return None
except Exception as e:
fn_print(f"未知异常: {e}")
return None
容错策略
- 网络异常: 自动重试 + 指数退避
- 业务异常: 记录日志 + 继续执行其他任务
- 数据异常: 数据校验 + 默认值处理
安全性考虑
1. 敏感信息保护
python
# 环境变量存储敏感信息
tc_cookies = get_env("tc_cookie", "@")
bark_key = os.environ.get('BARK_KEY', '')
# 日志脱敏处理
def mask_sensitive_data(data):
if isinstance(data, str) and len(data) > 8:
return data[:4] + "****" + data[-4:]
return data
2. 请求频率控制
python
# 任务间隔控制
await asyncio.sleep(task['browserTime'])
# 重试间隔
await asyncio.sleep(retry_delay * (attempt + 1))
3. User-Agent伪装
python
'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 TcTravel/11.0.0 tctype/wk'
扩展性设计
1. 插件化架构
python
class TaskPlugin:
"""任务插件基类"""
async def execute(self, client, headers):
raise NotImplementedError
class SignInPlugin(TaskPlugin):
"""签到插件"""
async def execute(self, client, headers):
# 具体签到逻辑
pass
class TaskListPlugin(TaskPlugin):
"""任务列表插件"""
async def execute(self, client, headers):
# 任务处理逻辑
pass
2. 配置化管理
python
# config.yaml
api:
base_url: "https://app.17u.cn/welfarecenter"
timeout: 60
retry_times: 3
push:
bark:
icon: "Travel.png"
group: "同程旅行"
switch: true
accounts:
- phone: "138****1234"
token: "xxx"
device: "xxx"
监控与运维
1. 执行状态监控
python
class ExecutionMonitor:
def __init__(self):
self.start_time = time.time()
self.success_count = 0
self.error_count = 0
def record_success(self):
self.success_count += 1
def record_error(self):
self.error_count += 1
def get_statistics(self):
execution_time = time.time() - self.start_time
return {
'execution_time': execution_time,
'success_rate': self.success_count / (self.success_count + self.error_count),
'total_processed': self.success_count + self.error_count
}
2. 健康检查机制
python
async def health_check():
"""系统健康检查"""
checks = {
'network': await check_network_connectivity(),
'api_status': await check_api_availability(),
'config': check_configuration_validity(),
'dependencies': check_dependencies()
}
return all(checks.values())
部署与自动化
1. Docker容器化
dockerfile
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "main.py"]
2. 定时任务配置
bash
# crontab配置
# 每天早上8点执行
0 8 * * * cd /path/to/script && python main.py
# 青龙面板配置
# 0 8 * * * tc_travel_sign.py
3. CI/CD集成
yaml
# .github/workflows/deploy.yml
name: Auto Deploy
on:
schedule:
- cron: '0 8 * * *'
jobs:
run-script:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: '3.9'
- name: Install dependencies
run: pip install -r requirements.txt
- name: Run script
env:
TC_COOKIE: ${{ secrets.TC_COOKIE }}
BARK_KEY: ${{ secrets.BARK_KEY }}
run: python main.py
性能基准测试
测试环境
- 硬件: Intel i7-10700K, 16GB RAM
- 网络: 100Mbps宽带
- Python版本: 3.9.7
性能数据
账号数量 | 串行执行时间 | 并行执行时间 | 性能提升 |
---|---|---|---|
1 | 15s | 15s | 1x |
5 | 75s | 18s | 4.2x |
10 | 150s | 22s | 6.8x |
20 | 300s | 28s | 10.7x |
内存使用情况
python
import psutil
import os
def monitor_memory():
process = psutil.Process(os.getpid())
memory_info = process.memory_info()
return {
'rss': memory_info.rss / 1024 / 1024, # MB
'vms': memory_info.vms / 1024 / 1024, # MB
'percent': process.memory_percent()
}
配置简单:
bash
# 环境变量配置
export tc_cookie="phone1#token1#device1@phone2#token2#device2"
export BARK_KEY="your_bark_key"
运行稳定:
- 连续运行30天无故障
- 自动处理网络异常
- 推送通知及时准确
结语
本文详细解析了同程旅行自动化签到脚本的完整技术实现,从基础的异步编程到高级的系统架构设计,为开发者提供了一个完整的自动化脚本开发框架。
免责声明: 本文所述技术方案仅用于学习和研究目的,请在合法合规的前提下使用相关技术。开发者应当遵守相关平台的使用条款和法律法规。