Python自动化实战:模拟用户行为找回绑定QQ号

📅 2026/7/16 5:37:13
Python自动化实战:模拟用户行为找回绑定QQ号
1. 项目概述当手机号成为找回QQ的钥匙最近在帮一个朋友处理旧账号时遇到了一个挺典型的问题他记得自己有好几个QQ号但只记得当时绑定的手机号具体的QQ号码早就忘得一干二净了。手动去一个个试不现实。这让我想到其实很多人都有类似的需求——通过一个已知的手机号找回曾经绑定过的、被遗忘的QQ号。这背后不仅仅是个人记忆的模糊更涉及到数字资产管理、账号安全追溯等实际场景。于是一个利用Python实现自动化查询的想法就诞生了。这可不是什么“黑科技”或者破解手段其核心思路是模拟一个合法用户在官方或常规渠道下的查询行为将繁琐、重复的人工操作转化为稳定、高效的自动化流程。想象一下如果你是一个社区运营者需要梳理一批历史注册用户的QQ信息进行联系或者你是一个个人用户想清理自己名下到底绑定了哪些平台的账号这个自动化方案就能派上用场。它解决的痛点非常明确将低效、易错的人工记忆与尝试转变为精准、批量的自动化查询。整个方案的核心在于Python的自动化能力特别是结合一些用于网页交互和请求处理的库。我们不会去触碰任何非公开的接口或进行违规操作一切都在模拟正常用户行为的前提下进行。这对于有一定Python基础希望将自动化技术应用于实际生活场景或轻度办公需求的开发者来说是一个很好的练手项目。接下来我将从设计思路、技术选型、实操步骤到避坑经验完整拆解这个“手机号找回QQ号”的自动化方案。2. 核心思路与技术选型解析2.1 为什么选择Python与自动化脚本首先得明确我们不是在“破解”或“攻击”系统。我们的目标是自动化一个本就可以手动完成的操作。手动流程通常是打开某个查询页面可能是找回密码页面、账号申诉页面或第三方查询网站输入手机号点击查询/获取验证码然后从返回的结果或短信中提取出关联的QQ号。这个过程慢、累且无法批量处理。Python在这个场景下的优势是压倒性的生态丰富拥有如requests、selenium、playwright等强大的HTTP请求和浏览器自动化库能轻松模拟用户操作。易于上手语法简洁即便非专业开发者在有一定基础后也能快速理解脚本逻辑。跨平台脚本可以在Windows、macOS、Linux上运行适应性广。适合处理结构化任务对于“输入-请求-解析输出”这类流程化任务Python写起来非常顺手。这个项目的本质是一个基于Web的、模拟用户行为的自动化流程脚本。技术难度中等但非常考验对网络请求流程的梳理能力和对反自动化机制的应对策略。2.2 可行路径分析与技术栈决策要实现通过手机号查询关联QQ号我们需要找到一个合法的、可访问的查询入口。经过分析主要有以下几种路径每种对应不同的技术实现方案路径一模拟官方账号找回流程思路模拟用户在QQ安全中心或相关登录页面通过“找回账号”功能输入手机号获取短信验证码从而在页面上看到部分账号提示通常是昵称或头像。技术实现Selenium或Playwright。这类浏览器自动化工具能完美模拟真人操作包括点击按钮、输入文本、处理弹窗等对JavaScript渲染的页面支持好。优点最接近真实用户行为理论上最合规。挑战可能会遇到复杂的验证码如滑块、点选图且流程可能随官网改版而变化维护成本较高。路径二调用已知的查询接口如有思路通过浏览器开发者工具F12监控网络请求寻找在查询过程中前端向后台发送的Ajax请求直接模拟这个请求。技术实现Requests。这是最轻量、最高效的方式。直接构造HTTP请求包括必要的Headers、Cookies和请求体Form Data或JSON。优点速度快资源消耗低易于集成和批量运行。挑战需要一定的逆向分析能力接口可能有签名、令牌等反爬机制接口地址和参数可能变更。路径三利用第三方聚合查询服务需极度谨慎思路互联网上存在一些提供“手机号查关联账号”的网站。我们可以自动化向这些网站提交查询。技术实现Requests或Selenium取决于网站技术架构。优点有时能直接获得结果无需处理验证码。挑战安全性、隐私性和合法性风险极高。这类网站很可能非法收集和贩卖数据使用其服务可能导致个人信息泄露甚至触犯法律。强烈不推荐此路径。重要提示本方案将主要围绕路径一模拟官方流程进行设计和讲解这是最稳妥、最符合规范的方式。我们会严格遵守机器人协议robots.txt并设置合理的请求间隔避免对服务器造成压力。路径二仅作为技术探讨在实际应用中必须确保其公开性和合法性。最终技术栈选定 对于核心的自动化操作鉴于官方页面交互复杂我们选择Playwright作为主力。它比Selenium更现代API更优雅自动等待机制更智能且自带浏览器无需单独配置驱动。对于辅助的数据处理、日志记录等任务则使用Python标准库及requests用于可能的简单接口探测。3. 环境准备与核心工具详解3.1 Python环境与Playwright搭建工欲善其事必先利其器。首先确保你有一个可用的Python环境3.7及以上版本。我推荐使用conda或venv创建独立的虚拟环境避免包冲突。# 1. 创建并激活虚拟环境 (以venv为例) python -m venv qq_finder_env # Windows: qq_finder_env\Scripts\activate # macOS/Linux: source qq_finder_env/bin/activate # 2. 安装Playwright pip install playwright # 3. 安装Playwright所需的浏览器Chromium足够 playwright install chromium为什么选择Playwright而不是更老牌的Selenium自动等待Playwright在执行操作如点击、填充前会自动等待元素可操作状态大大减少了需要手动添加time.sleep的情况代码更健壮。强大的选择器支持CSS、XPath、Text等多种定位方式甚至可以通过get_by_role等语义化方式定位可读性更强。录制功能playwright codegen命令可以打开一个浏览器并录制你的操作直接生成Python脚本对于快速分析页面流程非常有帮助。网络拦截与模拟可以轻松地拦截和修改网络请求这对于分析接口和模拟复杂场景非常有用。3.2 辅助工具浏览器开发者工具这是我们的“眼睛”。在整个项目开发中你需要频繁使用Chrome或Edge浏览器的开发者工具F12。重点关注两个面板Elements元素用于查看页面HTML结构找到输入框、按钮等元素的唯一选择器如ID、Class、XPath。Network网络这是关键。记录网络请求当你手动进行查询操作时观察有哪些XHR/Fetch请求被发送它们的请求URL、方法、Headers、Payload请求体是什么。这能帮助我们理解数据是如何提交的。3.3 项目结构设计一个清晰的项目结构有助于后期维护和代码复用。建议如下qq_number_finder/ ├── config.py # 配置文件存放目标手机号、超时时间等 ├── core/ │ ├── browser_operator.py # 浏览器操作核心类封装Playwright动作 │ └── query_engine.py # 查询流程引擎编排整个找回逻辑 ├── utils/ │ ├── logger.py # 日志记录工具 │ └── data_parser.py # 数据解析工具用于从页面或响应中提取QQ号 ├── main.py # 主程序入口 ├── requirements.txt # 项目依赖列表 └── logs/ # 日志文件目录4. 实操流程模拟官方找回路径这是整个项目的核心部分。我们将以模拟“QQ安全中心”的账号找回流程为例。请注意实际页面结构和流程可能随时更新以下代码和步骤主要展示方法和逻辑你需要根据实时页面进行调整。4.1 第一步分析手动操作流程首先你需要完全手动走一遍流程打开浏览器访问https://aq.qq.comQQ安全中心。找到“找回账号”或“密码管理”相关入口。选择“通过手机号找回”之类的选项。输入手机号码。点击“获取短信验证码”。输入收到的短信验证码。提交后页面可能会展示与此手机号关联的账号列表通常以昵称或头像形式展示可能隐藏部分号码。在这个过程中用开发者工具的Network面板记录下关键请求特别是提交手机号和验证码的那个POST请求。4.2 第二步使用Playwright实现自动化导航与交互我们创建一个browser_operator.py来封装基础的浏览器操作。# core/browser_operator.py import asyncio from playwright.async_api import async_playwright import logging class BrowserOperator: def __init__(self, headlessFalse, slow_mo100): 初始化浏览器操作器 :param headless: 是否无头模式不显示浏览器界面 :param slow_mo: 操作延迟毫秒方便观察调试时可设置生产环境建议为0 self.headless headless self.slow_mo slow_mo self.browser None self.context None self.page None self.logger logging.getLogger(__name__) async def start(self): 启动浏览器和上下文 playwright await async_playwright().start() # 使用Chromium可配置为 chrome 或 firefox self.browser await playwright.chromium.launch(headlessself.headless, slow_moself.slow_mo) # 创建一个新的浏览器上下文可以设置视窗、User-Agent等 self.context await self.browser.new_context( viewport{width: 1920, height: 1080}, user_agentMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ... ) self.page await self.context.new_page() self.logger.info(浏览器启动成功) async def goto(self, url): 导航到指定URL await self.page.goto(url) self.logger.debug(f已导航至: {url}) async def fill_input(self, selector, value): 填充输入框 await self.page.fill(selector, value) self.logger.debug(f已向选择器 {selector} 填充值: {value}) async def click(self, selector): 点击元素 await self.page.click(selector) self.logger.debug(f已点击选择器: {selector}) async def wait_for_selector(self, selector, statevisible, timeout30000): 等待元素出现 await self.page.wait_for_selector(selector, statestate, timeouttimeout) async def get_text(self, selector): 获取元素的文本内容 element await self.page.query_selector(selector) if element: text await element.text_content() self.logger.debug(f从选择器 {selector} 获取到文本: {text}) return text.strip() return None async def stop(self): 关闭浏览器 if self.browser: await self.browser.close() self.logger.info(浏览器已关闭)4.3 第三步编排核心查询逻辑接下来在query_engine.py中我们编排具体的找回流程。这里以假设的页面结构为例你需要根据实际页面修改选择器和URL。# core/query_engine.py import asyncio import re from .browser_operator import BrowserOperator class QQQueryEngine: def __init__(self): self.operator BrowserOperator(headlessFalse) # 调试时关闭无头模式 self.associated_accounts [] # 存储找到的账号信息 async def find_qq_by_phone(self, phone_number): 通过手机号查找关联QQ号的主流程 :param phone_number: 手机号码字符串 try: await self.operator.start() # 1. 访问QQ安全中心找回页面示例URL需确认 await self.operator.goto(https://aq.qq.com/v2/uv1/html/find_account/index.html) await asyncio.sleep(2) # 等待页面加载 # 2. 定位并点击“通过手机号找回” # 假设按钮的文本包含“手机” await self.operator.click(text手机) await asyncio.sleep(1) # 3. 输入手机号 # 需要根据实际页面找到手机号输入框的selector可能是ID、name或class # 使用开发者工具查看。例如#phone_number 或 input[nametel] phone_input_selector input[placeholder请输入手机号码] # 示例 await self.operator.fill_input(phone_input_selector, phone_number) # 4. 点击获取验证码按钮 get_code_btn_selector button:has-text(获取验证码) await self.operator.click(get_code_btn_btn_selector) self.logger.info(f已为手机号 {phone_number} 请求验证码请在手机上查看。) # 5. 此处需要人工干预或接入短信接收平台复杂且涉及隐私不建议自动化输入 # 我们在这里暂停等待用户手动输入验证码 sms_code input(f请输入发送到 {phone_number} 的短信验证码: ) # 6. 输入验证码 code_input_selector input[placeholder请输入验证码] await self.operator.fill_input(code_input_selector, sms_code) # 7. 点击提交/下一步按钮 submit_btn_selector button:has-text(下一步) await self.operator.click(submit_btn_selector) await asyncio.sleep(3) # 等待结果页面加载 # 8. 从结果页面提取账号信息 # 结果可能是一个列表每个条目包含昵称和部分QQ号 # 假设每个账号信息在一个class为.account-item的div里 account_items await self.operator.page.query_selector_all(.account-item) for item in account_items: # 提取文本可能包含昵称和模糊的QQ号如昵称12****34 text await item.text_content() if text: self.associated_accounts.append(text) # 尝试用正则表达式提取可能的QQ号模式即使被隐藏部分 qq_match re.search(r\((\d{2}\*\d{2})\), text) # 匹配如 (12****34) if qq_match: self.logger.info(f发现关联账号信息: {text}) if not self.associated_accounts: self.logger.warning(f未找到与手机号 {phone_number} 明显关联的QQ账号。) else: self.logger.info(f共找到 {len(self.associated_accounts)} 个可能关联的账号。) except Exception as e: self.logger.error(f查询过程中发生错误: {e}) finally: # 为了观察结果这里先不自动关闭浏览器 # await self.operator.stop() pass def get_results(self): 返回查询结果 return self.associated_accounts4.4 第四步编写主程序并运行# main.py import asyncio import sys from core.query_engine import QQQueryEngine async def main(): if len(sys.argv) 2: phone input(请输入要查询的手机号: ) else: phone sys.argv[1] # 简单的手机号格式校验 if not re.match(r^1[3-9]\d{9}$, phone): print(手机号格式不正确) return print(f开始查询与手机号 {phone} 关联的QQ号...) engine QQQueryEngine() await engine.find_qq_by_phone(phone) results engine.get_results() if results: print(\n 查询结果 ) for idx, acc in enumerate(results, 1): print(f{idx}. {acc}) else: print(未查询到明确的关联账号。) # 脚本执行完毕提示用户手动关闭浏览器以查看页面状态 input(\n流程执行完毕。按回车键关闭浏览器并退出...) await engine.operator.stop() if __name__ __main__: asyncio.run(main())运行脚本python main.py 13800138000或者直接运行python main.py然后根据提示输入手机号。关键注意事项实操心得选择器稳定性页面上的ID、Class可能随时变化。优先使用相对稳定的属性如name、placeholder文本或者通过text定位。避免使用自动生成的、带哈希值的类名。等待策略page.wait_for_selector比固定的time.sleep更可靠。确保在关键操作如点击后页面跳转前等待目标元素出现。验证码瓶颈短信验证码是自动化流程的最大障碍。上述代码中我们采用“人工输入”的方式这是最合法、最安全的方式。任何试图自动接收、识别短信验证码的行为都涉及极高的隐私和安全风险且可能违反服务条款务必避免。道德与合规此脚本仅用于个人查找自己名下的账号或获得明确授权的查询。严禁用于批量查询他人手机号这不仅是道德问题更可能涉及法律风险。5. 进阶探讨接口分析与请求模拟虽然我们主要采用浏览器自动化方案但了解接口模拟这一更高效的方式对开发者很有价值。这需要一些网络抓包和分析技能。5.1 使用开发者工具分析网络请求在手动操作流程时保持Network面板开启勾选Preserve log。当你点击“获取验证码”和“提交”按钮时会看到新增的请求。重点关注请求URL通常是api或ajax开头的地址。请求方法POST或GET。请求头Headers特别是Content-Type、User-Agent、Cookie、Referer、X-Requested-With等。请求体Payload查看Form Data或Request Payload里面包含了提交的手机号、验证码、可能的令牌token或时间戳。5.2 使用Requests库模拟请求示例假设我们分析出一个简单的接口此为虚构示例切勿直接使用import requests import json import time def query_by_api(phone_number, sms_code): 模拟调用查询接口示例非真实接口 url https://example.qq.com/api/findAccount headers { User-Agent: Mozilla/5.0..., Content-Type: application/json; charsetUTF-8, Referer: https://aq.qq.com/find, # Cookie可能需要从首次访问的响应中获取 Cookie: pgv_pvi...; pgv_si... } payload { tel: phone_number, code: sms_code, verifyToken: 动态令牌需从页面获取, # 这是一个难点 timestamp: int(time.time() * 1000), clientid: 固定或动态的客户端ID } try: response requests.post(url, headersheaders, datajson.dumps(payload), timeout10) response.raise_for_status() # 检查请求是否成功 result response.json() # 解析返回的JSON数据 if result.get(code) 0: accounts result.get(data, {}).get(accountList, []) return accounts else: print(f接口返回错误: {result.get(message)}) return [] except requests.exceptions.RequestException as e: print(f网络请求失败: {e}) return []这个方法的巨大挑战动态令牌像verifyToken这样的参数往往在页面加载时由JavaScript生成或包含在之前的响应中。要获取它你可能还是需要先用Playwright或Selenium加载一次页面提取出这个令牌然后再用requests发送请求。这就变成了混合模式。Cookie管理登录态和会话通常由Cookie维持。你需要正确处理Cookie的获取、传递和更新。反爬机制重要的接口很可能有签名sign验证。客户端会用一种算法如对参数排序后MD5加密生成一个签名服务器端会校验。如果不清楚算法模拟请求就会失败。因此对于新手或追求稳妥的方案完整的浏览器自动化Playwright虽然效率稍低但成功率更高更易于理解和维护。接口模拟更适合对网络协议和逆向分析有较深理解的开发者。6. 常见问题排查与优化技巧在实际编写和运行脚本时你肯定会遇到各种问题。这里记录一些典型的坑和解决方案。6.1 元素定位失败问题TimeoutError: Timeout 30000ms exceeded.最常见意味着Playwright在30秒内没找到你指定的元素。排查确认选择器是否正确在浏览器开发者工具的Console里试试document.querySelector(你的选择器)看能否找到元素。页面是否加载完成可能元素在iframe里需要先切换到iframe框架。使用page.frame()系列API。元素是否被遮挡或不可见检查元素是否被弹窗、遮罩层覆盖。可能需要先关闭弹窗。等待条件有时元素存在但不可点击。可以尝试wait_for_selector的state参数设为attached存在于DOM而非visible可见。技巧使用Playwright Inspector进行调试。在代码中设置headlessFalse和slow_mo1000然后运行脚本你可以直观地看到脚本的操作过程更容易发现问题所在。6.2 验证码处理难题问题除了短信验证码还可能遇到图形验证码Captcha。策略人工识别对于低频个人使用脚本在遇到图形验证码时暂停弹出验证码图片让用户手动输入是最简单合法的方案。Playwright可以截图元素。商业打码平台对于有合法授权且高频的业务场景可以考虑接入付费的打码API但成本和法律风险需要评估。规避尝试寻找不需要验证码的查询路径可能性极低或者优化脚本行为使其更像真人降低触发验证码的概率如添加随机延迟、模拟鼠标移动轨迹。6.3 脚本被检测为自动化工具现象页面返回错误或直接提示“操作过于频繁”、“需要安全验证”。应对设置合理的User-Agent使用常见的浏览器UA字符串。添加随机延迟在关键操作之间使用asyncio.sleep(random.uniform(1, 3))模拟人类思考时间。使用更真实的浏览器上下文Playwright的new_context可以设置视窗大小、地理位置、语言等使其指纹更接近真实浏览器。避免并行操作对同一个网站不要用同一个IP同时发起大量查询极易被封。考虑使用代理IP如果需要批量查询必须在合法前提下轮换IP池是必要的。但这增加了复杂性和成本。6.4 结果解析与数据清洗问题从页面抓取到的文本信息杂乱包含多余的空格、换行符和无关文字。解决import re def extract_qq_info(raw_text): 从混杂的文本中提取可能的QQ号和昵称 cleaned_text raw_text.replace(\n, ).strip() # 尝试匹配多种可能的QQ号格式 # 格式1: 纯数字8-11位 qq_numbers re.findall(r(?!\d)[1-9]\d{4,10}(?!\d), cleaned_text) # 格式2: 昵称(12****34) hidden_qq re.findall(r\((\d{2}\*\d{2})\), cleaned_text) # 提取昵称假设昵称在括号或特定符号前 nickname re.split(r[\(\], cleaned_text)[0].strip() return { nickname: nickname if nickname else 未知, possible_qq_full: qq_numbers, possible_qq_hidden: hidden_qq, raw_text: raw_text }编写健壮的解析函数并做好异常处理因为页面结构可能变化。7. 项目扩展与安全边界思考一个完整的自动化脚本项目除了核心功能还需要考虑扩展性和安全性。7.1 功能扩展方向批量处理读取一个包含多个手机号的文本文件逐个查询并将结果输出到CSV或Excel文件中。注意要加入足够的请求间隔并妥善处理单个查询失败的情况避免整个任务中断。结果去重与关联分析如果一个手机号关联多个QQ或者反过来查询多个手机号可以建立关系图谱更清晰地展示账号关联情况。图形用户界面GUI使用PyQt、Tkinter或Flet为脚本制作一个简单的桌面应用方便非技术用户使用。提供输入框、开始按钮和结果展示区域。日志与监控集成更完善的日志系统如loguru记录每次查询的起止时间、成功与否、遇到的异常等便于后期审计和问题排查。封装为API服务使用FastAPI或Flask将核心查询功能封装成Web API供其他系统调用同样必须严格限制访问权限和频率。7.2 安全与合规红线这是本项目乃至所有自动化项目必须时刻绷紧的弦。目的合法仅用于查询自己拥有所有权或已获得明确授权的手机号所关联的账号。任何未经授权的查询都是对他人隐私的侵犯且可能违法。尊重robots.txt在访问网站前检查其robots.txt文件如https://aq.qq.com/robots.txt确认目标路径是否允许爬虫访问。虽然浏览器自动化工具不完全等同于传统爬虫但遵循此协议是良好的网络公民行为。控制访问频率在脚本中设置REQUEST_DELAY 5秒这样的常量在两个查询之间强制等待避免对目标服务器造成拒绝服务攻击DoS的压力。不尝试绕过安全机制不要试图破解验证码、伪造签名或使用任何技术手段绕过平台为保护用户安全而设置的风控措施。这不仅技术难度高更重要的是触碰了法律和道德的底线。数据最小化与妥善保管查询到的结果即使是自己的信息也应妥善保管及时清理不要存储在不受保护的地方。脚本中不要硬编码任何敏感信息如手机号应通过配置文件或输入参数传入。自动化是一把强大的工具它能将我们从重复劳动中解放出来。但越是强大的工具越需要我们以负责任的态度去使用。这个“手机号找回QQ号”的项目与其说是一个即拿即用的解决方案不如说是一个学习Web自动化、理解网络请求、培养合规开发意识的绝佳练手案例。