使用Python+Selenium登录X(Twitter)遇TimeoutException问题求助
问题
尝试用Python+Selenium实现X(原Twitter)自动登录,代码如下:
def tweet_at_provider(self): self.driver.get("https://twitter.com/?logout=1703191446777") wait = WebDriverWait(self.driver, 30) sign_in=wait.until(EC.presence_of_element_located((By.XPATH,'//*[@id="react-root"]/div/div/div[2]/main/div/div/div[1]/div/div/div[3]/div[5]/a/div'))) sign_in.click() time.sleep(3) email=self.driver.find_element(By.XPATH,'//*[@id="layers"]/div[2]/div/div/div/div/div/div[2]/div[2]/div/div/div[2]/div[2]/div/div/div/div[5]/label/div/div[2]/div/input') email.send_keys(X_EMAIL) email.send_keys(Keys.ENTER) wait = WebDriverWait(self.driver, 30) next_button= wait.until(EC.presence_of_element_located((By.XPATH,'//*[@id="layers"]/div[2]/div/div/div/div/div/div[2]/div[2]/div/div/div[2]/div[2]/div/div/div/div[6]/div'))) next_button.click() wait=WebDriverWait(self.driver, 30) password=wait.until(EC.presence_of_element_located((By.XPATH,'//*[@id="layers"]/div[2]/div/div/div/div/div/div[2]/div[2]/div/div/div[2]/div[2]/div[1]/div/div/div[3]/div/label/div/div[2]/div[1]/input'))) password.send_keys(X_PASSWORD) password.send_keys(Keys.ENTER) wait = WebDriverWait(self.driver, 30) log_in=wait.until(EC.presence_of_element_located((By.XPATH,'//*[@id="layers"]/div[2]/div/div/div/div/div/div[2]/div[2]/div/div/div[2]/div[2]/div[2]/div/div[1]/div/div/div/div'))) log_in.click()
运行后抛出超时错误:
Traceback (most recent call last): File "C:\Users\38161\PycharmProjects\XComplainBot\main.py", line 46, in <module> bot.tweet_at_provider() File "C:\Users\38161\PycharmProjects\XComplainBot\main.py", line 35, in tweet_at_provider next_button= wait.until(EC.presence_of_element_located((By.XPATH,'//*[@id="layers"]/div[2]/div/div/div/div/div/div[2]/div[2]/div/div/div[2]/div[2]/div/div/div/div[6]/div'))) File "C:\Users\38161\PycharmProjects\XComplainBot\venv\lib\site-packages\selenium\webdriver\support\wait.py", line 105, in until raise TimeoutException(message, screen, stacktrace) selenium.common.exceptions.TimeoutException: Message: Stacktrace: GetHandleVerifier [0x00007FF620092142+3514994] (No symbol) [0x00007FF61FCB0CE2] (No symbol) [0x00007FF61FB576AA] (No symbol) [0x00007FF61FBA1860] (No symbol) [0x00007FF61FBA197C] (No symbol) [0x00007FF61FBE4EE7] (No symbol) [0x00007FF61FBC602F] (No symbol) [0x00007FF61FBE28F6] (No symbol) [0x00007FF61FBC5D93] (No symbol) [0x00007FF61FB94BDC] (No symbol) [0x00007FF61FB95C64] GetHandleVerifier [0x00007FF6200BE16B+3695259] GetHandleVerifier [0x00007FF620116737+4057191] GetHandleVerifier [0x00007FF62010E4E3+4023827] GetHandleVerifier [0x00007FF61FDE04F9+689705] (No symbol) [0x00007FF61FCBC048] (No symbol) [0x00007FF61FCB8044] (No symbol) [0x00007FF61FCB81C9] (No symbol) [0x00007FF61FCA88C4] BaseThreadInitThunk [0x00007FF896867344+20] RtlUserThreadStart [0x00007FF896E626B1+33]
已尝试延长等待时间到60秒,问题依旧。程序能点击“下一步”按钮,但无法输入密码。
解决方案
- 替换硬编码XPATH为语义化定位:X的页面结构频繁变动,长串XPATH极易失效。改用元素的
data-testid属性或可见文本定位,这类定位更稳定,不受页面布局变动影响。 - 用
element_to_be_clickable替代presence_of_element_located:元素存在不代表可交互,等待元素可点击更符合操作逻辑,避免点击无效元素导致流程中断。 - 移除不必要的
time.sleep:改用显式等待,让代码根据元素状态动态等待,减少不必要的等待时间,提升稳定性。 - 处理人机验证:X会对自动化操作触发验证机制,可尝试使用
undetected-chromedriver替代常规ChromeDriver,伪装浏览器指纹;或手动完成验证后再执行自动化流程。
修改后的示例代码:
from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.keys import Keys def tweet_at_provider(self): # 直接访问登录页,避免logout参数带来的页面跳转问题 self.driver.get("https://twitter.com/login") wait = WebDriverWait(self.driver, 30) # 等待并点击登录按钮 sign_in = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '[data-testid="loginButton"]'))) sign_in.click() # 输入邮箱/用户名 email_input = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '[data-testid="ocfEnterTextTextInput"]'))) email_input.send_keys(X_EMAIL) email_input.send_keys(Keys.ENTER) # 等待下一步按钮并点击 next_btn = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '[data-testid="ocfEnterTextNextButton"]'))) next_btn.click() # 输入密码 password_input = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '[data-testid="LoginFormPassword"]'))) password_input.send_keys(X_PASSWORD) # 点击登录按钮 login_btn = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '[data-testid="LoginForm_Login_Button"]'))) login_btn.click()
内容的提问来源于stack exchange,提问作者luna28blue
相关产品推荐
相关产品推荐

