""" 小红书登录页面调试脚本 用于调试登录页面结构和元素选择器 """ import asyncio import sys from xhs_login import XHSLoginService async def debug_login_page(proxy_index: int = 0): """ 调试登录页面,查看页面结构和可用元素 """ print(f"\n{'='*60}") print(f"🔍 调试小红书登录页面") print(f"{'='*60}") # 从代理配置获取代理信息 from damai_proxy_config import get_proxy_config proxy_config = get_proxy_config(proxy_index) proxy_server = proxy_config['server'].replace('http://', '') proxy_url = f"http://{proxy_config['username']}:{proxy_config['password']}@{proxy_server}" print(f"✅ 使用代理: 代理{proxy_index + 1}") print(f" 代理服务器: {proxy_config['server']}") # 创建登录服务 login_service = XHSLoginService(use_pool=False) # 不使用池,便于调试 try: # 初始化浏览器(使用代理) user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36' await login_service.init_browser(proxy=proxy_url, user_agent=user_agent) print("✅ 浏览器初始化成功(已启用代理)") # 访问登录页面 print(f"\n🌐 访问小红书创作者平台登录页...") await login_service.page.goto('https://creator.xiaohongshu.com/login', wait_until='networkidle', timeout=30000) await asyncio.sleep(5) # 等待更长时间让页面完全加载 # 获取页面标题和URL title = await login_service.page.title() url = login_service.page.url print(f"✅ 页面加载完成") print(f" 标题: {title}") print(f" URL: {url}") # 获取页面内容 content = await login_service.page.content() print(f" 页面内容长度: {len(content)} 字符") # 查找所有input元素 print(f"\n🔍 查找所有input元素...") inputs = await login_service.page.query_selector_all('input') print(f" 找到 {len(inputs)} 个input元素") for i, inp in enumerate(inputs): try: placeholder = await inp.get_attribute('placeholder') input_type = await inp.get_attribute('type') name = await inp.get_attribute('name') class_name = await inp.get_attribute('class') id_attr = await inp.get_attribute('id') print(f" Input {i+1}:") print(f" - placeholder: {placeholder}") print(f" - type: {input_type}") print(f" - name: {name}") print(f" - id: {id_attr}") print(f" - class: {class_name}") except Exception as e: print(f" Input {i+1}: 获取属性失败 - {str(e)}") # 查找所有可能的手机号输入框选择器 print(f"\n🔍 尝试常见手机号输入框选择器...") phone_selectors = [ 'input[placeholder="手机号"]', 'input[placeholder*="手机"]', 'input[type="tel"]', 'input[type="text"][placeholder*="号"]', 'input[placeholder*="Phone"]', 'input[name*="phone"]', 'input[placeholder*="号码"]', 'input[placeholder*="mobile"]', 'input[placeholder*="Mobile"]' ] found_inputs = [] for selector in phone_selectors: try: element = await login_service.page.query_selector(selector) if element: found_inputs.append((selector, element)) placeholder = await element.get_attribute('placeholder') print(f" ✅ 找到: {selector} (placeholder: {placeholder})") except Exception as e: print(f" ❌ 选择器 {selector} 失败: {str(e)}") if not found_inputs: print(" ❌ 未找到任何手机号相关输入框") # 查找所有按钮元素 print(f"\n🔍 查找所有button元素...") buttons = await login_service.page.query_selector_all('button') print(f" 找到 {len(buttons)} 个button元素") for i, btn in enumerate(buttons[:10]): # 只显示前10个 try: text = await btn.inner_text() class_name = await btn.get_attribute('class') id_attr = await btn.get_attribute('id') print(f" Button {i+1}:") print(f" - text: '{text.strip()}'") print(f" - class: {class_name}") print(f" - id: {id_attr}") except Exception as e: print(f" Button {i+1}: 获取信息失败 - {str(e)}") # 查找发送验证码按钮 print(f"\n🔍 尝试常见发送验证码按钮选择器...") code_selectors = [ 'text="发送验证码"', 'text="获取验证码"', 'text="发送"', 'text="获取"', 'button:has-text("验证码")', 'button:has-text("发送")', 'button:has-text("获取")', '[class*="send"]', '[class*="code"]', '[class*="verify"]' ] found_buttons = [] for selector in code_selectors: try: element = await login_service.page.query_selector(selector) if element: found_buttons.append((selector, element)) text = await element.inner_text() print(f" ✅ 找到: {selector} (text: '{text.strip()}')") except Exception as e: print(f" ❌ 选择器 {selector} 失败: {str(e)}") if not found_buttons: print(" ❌ 未找到任何验证码相关按钮") # 打印页面HTML片段(用于分析结构) print(f"\n📄 页面HTML片段(前1000字符)...") print(content[:1000]) print(f"\n📄 页面HTML片段(1000-2000字符)...") print(content[1000:2000]) # 等待用户交互(保持浏览器打开) print(f"\n⏸️ 浏览器保持打开状态,您可以手动检查页面") print(f" URL: {url}") print(f" 按 Ctrl+C 关闭浏览器...") try: while True: await asyncio.sleep(1) except KeyboardInterrupt: print(f"\n⏹️ 用户中断,关闭浏览器...") except Exception as e: print(f"❌ 调试过程异常: {str(e)}") import traceback traceback.print_exc() finally: await login_service.close_browser() async def main(): """主函数""" print("="*60) print("🔍 小红书登录页面调试工具") print("="*60) print("\n此工具将帮助您分析小红书登录页面的结构") print("以便正确识别手机号输入框和验证码按钮") proxy_choice = input("\n请选择代理 (0 或 1, 默认为0): ").strip() if proxy_choice not in ['0', '1']: proxy_choice = '0' proxy_idx = int(proxy_choice) await debug_login_page(proxy_idx) print(f"\n{'='*60}") print("✅ 调试完成!") print("="*60) if __name__ == "__main__": # Windows环境下设置事件循环策略 if sys.platform == 'win32': asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy()) # 运行调试 asyncio.run(main())