如何实现网页爬取并等待特定事件?Selenium+2captcha验证码回传困境
解决2captcha结果回传与Selenium等待的问题
核心思路
用你的LAMP服务器做中转节点:2captcha将识别结果推送到服务器的回调接口,Selenium爬虫通过轮询服务器的存储(数据库/缓存)获取结果,同时保持阻塞等待,避免无效资源消耗。
步骤1:实现LAMP端的回调接收接口(PHP示例)
在服务器上创建captcha_callback.php文件,负责接收2captcha的POST请求并存储结果:
<?php // 连接MySQL数据库(需提前建表:task_id VARCHAR(50) PRIMARY KEY, code VARCHAR(10), status TINYINT DEFAULT 0) $conn = new mysqli('localhost', '你的数据库用户名', '你的数据库密码', 'captcha_db'); if ($conn->connect_error) die("数据库连接失败: " . $conn->connect_error); // 接收2captcha传递的参数 $taskId = $_POST['taskId'] ?? ''; $code = $_POST['code'] ?? ''; if ($taskId && $code) { // 插入或更新验证码结果 $stmt = $conn->prepare("REPLACE INTO captcha_results (task_id, code, status) VALUES (?, ?, 1)"); $stmt->bind_param("ss", $taskId, $code); $stmt->execute(); $stmt->close(); echo "OK"; // 必须返回200状态和OK,告知2captcha回调成功 } else { http_response_code(400); echo "无效参数"; } $conn->close(); ?>
步骤2:Selenium爬虫端的处理逻辑(Python示例)
- 提交验证码到2captcha并记录任务ID:
import requests from selenium import webdriver from selenium.webdriver.common.by import By import time # 初始化Selenium driver = webdriver.Chrome() driver.get("目标验证码页面") # 假设此处已获取到验证码图片的Base64字符串,存为captcha_base64 # (可通过Selenium截图、提取页面img标签的base64属性实现) # 提交验证码到2captcha,指定回调URL api_key = "你的2captcha API密钥" payload = { "key": api_key, "method": "base64", "body": captcha_base64, "pingback": "http://你的LAMP服务器公网地址/captcha_callback.php" } response = requests.post("https://2captcha.com/in.php", data=payload) if response.text.startswith("OK|"): task_id = response.text.split("|")[1] else: print("验证码提交失败") driver.quit() exit()
- 实现阻塞等待结果的逻辑:
# 轮询数据库获取结果,设置超时时间 timeout = 60 # 最多等待60秒 start_time = time.time() captcha_code = None # 连接同个数据库 import mysql.connector db_conn = mysql.connector.connect( host="localhost", user="你的数据库用户名", password="你的数据库密码", database="captcha_db" ) cursor = db_conn.cursor() while time.time() - start_time < timeout: cursor.execute("SELECT code FROM captcha_results WHERE task_id = %s AND status = 1", (task_id,)) result = cursor.fetchone() if result: captcha_code = result[0] break time.sleep(5) # 每5秒查询一次 if captcha_code: # 填入验证码并提交 driver.find_element(By.ID, "验证码输入框ID").send_keys(captcha_code) driver.find_element(By.ID, "提交按钮ID").click() else: print("等待超时,未获取到验证码结果") # 清理资源 cursor.close() db_conn.close() driver.quit()
额外注意事项
- 确保LAMP服务器有公网IP,能被2captcha访问(内网环境无法接收回调)。
- 可替换MySQL为Redis做缓存,提升轮询查询的速度。
- 2captcha的回调参数名可能有细微差异,需参考官方文档调整字段名。
内容的提问来源于stack exchange,提问作者alexpan
相关产品推荐
相关产品推荐

