无需API,用Python+Selenium+ChromeDriver实现推特发推遇阻求助
解决Twitter无API发推的ElementClickInterceptedException错误
近期Twitter宣布API开始收费,我在Ubuntu环境下尝试用Python+Selenium不通过API发推,登录成功后遇到如下错误:
selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <div dir="ltr" class="css-901oao r-18jsvk2 r-37j5jr r-a023e6 r-16dba41 r-rjixqe r-bcqeeo r-qvutc0">...</div> is not clickable at point (0, 1). Other element would receive the click: <header role="banner" class="css-1dbjc4n r-obd0qt r-16y2uox r-lrvibr r-1g40b8q">...</header>
原代码如下:
from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.chrome.options import Options from selenium.webdriver.chrome.service import Service from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.by import By from webdriver_manager.chrome import ChromeDriverManager options = Options() options.add_argument('--headless') options.add_argument('--no-sandbox') options.add_argument('--disable-dev-shm-usage') userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36" options.add_argument(f'user-agent={userAgent}') browser = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options) url = 'https://twitter.com/login' # change this to your username and password userUsername = 'user' userPassword = 'pw' def main(): browser.get(url) browser.implicitly_wait(5) user = browser.find_element("name", "text") user.send_keys(userUsername) user.send_keys(Keys.ENTER) browser.implicitly_wait(2) password = browser.find_element("name", "password") password.send_keys(userPassword) browser.implicitly_wait(5) password.send_keys(Keys.ENTER) browser.implicitly_wait(0) button1 = browser.find_element(By.CSS_SELECTOR,'div[dir="ltr"]') button1.click() browser.implicitly_wait(5) tweet = browser.find_element(By.CSS_SELECTOR,"br[data-text='true']") tweet.click() browser.implicitly_wait(1) tweet.send_keys('Testing1234') button2 = browser.find_element(By.CSS_SELECTOR,"div[data-testid='tweetButtonInline']") button2.click() browser.close() main()
问题分析与修复方案
- 元素定位太宽泛:原代码用
div[dir="ltr"]定位的元素不唯一,且被页面header遮挡,导致点击被拦截。需要改用Twitter页面提供的data-testid属性精准定位推文输入区域。 - 等待机制混乱:混合使用
implicitly_wait会导致不可预测的等待行为,统一使用显式等待(WebDriverWait)确保元素加载完成并可交互。 - 无头窗口尺寸问题:无头模式默认窗口过小,部分元素可能超出视图范围,需设置合适的窗口大小。
修改后的代码
from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.chrome.options import Options from selenium.webdriver.chrome.service import Service from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.by import By from webdriver_manager.chrome import ChromeDriverManager options = Options() options.add_argument('--headless') options.add_argument('--no-sandbox') options.add_argument('--disable-dev-shm-usage') # 设置无头模式窗口大小,避免元素超出视图 options.add_argument('--window-size=1920,1080') userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36" options.add_argument(f'user-agent={userAgent}') browser = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options) wait = WebDriverWait(browser, 10) # 显式等待最长10秒 url = 'https://twitter.com/login' # 修改为你的账号密码 userUsername = 'user' userPassword = 'pw' def main(): browser.get(url) # 等待用户名输入框并输入 user = wait.until(EC.visibility_of_element_located((By.NAME, "text"))) user.send_keys(userUsername) user.send_keys(Keys.ENTER) # 等待密码输入框并输入 password = wait.until(EC.visibility_of_element_located((By.NAME, "password"))) password.send_keys(userPassword) password.send_keys(Keys.ENTER) # 等待推文输入区域并点击 tweet_input = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'div[data-testid="tweetTextarea_0"]'))) tweet_input.click() # 输入推文内容 tweet_input.send_keys('Testing1234') # 等待发布按钮并点击 tweet_button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'div[data-testid="tweetButtonInline"]'))) tweet_button.click() browser.close() if __name__ == "__main__": main()
额外说明
- 若登录时遇到人机验证,可能需要添加验证码处理逻辑,或暂时关闭无头模式手动通过验证后再切换回无头。
- Twitter页面元素可能会更新,若后续定位失效,需重新查看页面元素的
data-testid或其他属性调整定位器。
内容的提问来源于stack exchange,提问作者Me Myself
相关产品推荐
相关产品推荐

