一、工具准备与核心原理
搞自动化抢票脚本必备三件套(划重点):
- Python基础环境(建议3.8+版本)
- 浏览器驱动(推荐ChromeDriver)
- 关键库安装:
pip install selenium requests beautifulsoup4
核心原理示意图(自己画的):
用户操作 --> 浏览器模拟 --> 页面元素定位 --> 自动化提交
\-> 接口直连 --> 数据抓取 --> 自动提交
二、两种主流方案对比
方案A:Selenium浏览器模拟(新手友好)
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("https://www.12306.cn")
# 登录操作(关键步骤!)
driver.find_element(By.ID, "username").send_keys("your_account")
driver.find_element(By.ID, "password").send_keys("your_pwd")
driver.find_element(By.ID, "loginBtn").click()
# 抢票流程示例
while True:
try:
driver.find_element(By.CSS_SELECTOR, ".ticket-available").click()
break
except:
driver.refresh()
优势:可视化操作,适合动态页面
缺点:速度较慢,需要处理弹窗
方案B:Requests直连接口(进阶推荐)
import requests
session = requests.Session()
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit..."
}
# 保持会话状态
login_url = "https://kyfw.12306.cn/passport/web/login"
data = {
"username": "your_account",
"password": "your_pwd_encrypted" # 注意加密处理!
}
session.post(login_url, data=data)
# 查询余票接口
query_url = "https://kyfw.12306.cn/otn/leftTicket/query"
params = {
"leftTicketDTO.train_date": "2024-08-01",
"leftTicketDTO.from_station": "BJP",
"leftTicketDTO.to_station": "SHH"
}
response = session.get(query_url, params=params)
关键点:
- 需要抓取接口参数(建议用浏览器开发者工具)
- 参数加密处理(重要!)
- 保持会话状态
三、三大核心难题破解
1. 验证码处理(最头疼的部分!)
推荐方案:
- 使用第三方打码平台(注意选择正规服务商)
- 机器学习方案(需训练模型)
- 手动识别调试模式(开发阶段用)
# 云打码示例
def crack_captcha(image_path):
api_url = "https://api.captcha.com/solve"
files = {'image': open(image_path, 'rb')}
response = requests.post(api_url, files=files)
return response.json()['result']
2. 高频请求限制
应对策略:
- 随机请求间隔(0.5-3秒)
- 使用代理IP池(重要!)
- 伪造请求头信息
import random
import time
def smart_delay():
time.sleep(random.uniform(0.5, 2.5))
3. 余票监控优化
高性能方案:
from concurrent.futures import ThreadPoolExecutor
def monitor_tickets(stations):
with ThreadPoolExecutor(max_workers=5) as executor:
futures = [executor.submit(check_single, s) for s in stations]
for future in as_completed(futures):
if future.result():
return future.result()
四、六个实战优化技巧
- 缓存利用:本地保存查询结果
- 失败重试机制(重要!):
from tenacity import retry, stop_after_attempt
@retry(stop=stop_after_attempt(3))
def submit_order():
# 订单提交代码
- 日志记录系统(必备!):
import logging
logging.basicConfig(
filename='ticket.log',
level=logging.INFO,
format='%(asctime)s - %(levelname)s: %(message)s'
)
- 邮件/微信通知:
import smtplib
def send_notification(msg):
server = smtplib.SMTP('smtp.xxx.com', 587)
server.starttls()
server.login("your_email", "password")
server.sendmail("from", "to", msg)
- 自动化测试模块(提升稳定性):
import unittest
class TestTicketScript(unittest.TestCase):
def test_login(self):
# 测试登录功能
- 配置参数化(方便维护):
import configparser
config = configparser.ConfigParser()
config.read('config.ini')
username = config.get('AUTH', 'USERNAME')
五、特别提醒(必看!)
- 遵守网站服务条款(重要!)
- 设置合理的请求频率
- 优先使用官方API
- 注意个人信息安全
- 避免商业用途(个人学习为主)
最后想说,开发这类脚本最重要的是理解其底层原理。建议先从简单的浏览器自动化做起,逐步过渡到接口调用。过程中会遇到各种反爬机制,需要保持耐心多调试。代码示例仅供参考,具体实现要根据目标网站的实际情况调整。