Selenium调用fetch请求发Twitter推文失败,手动控制台执行正常
问题:Selenium发送Twitter fetch请求被拒绝的原因分析
问题描述
我正在开发一个自动发布Twitter推文的机器人,计划使用Selenium重复发送fetch请求。已在浏览器控制台中重放该fetch请求,能够正常执行;但通过Selenium发送请求时却持续被拒绝,直接在Selenium控制台执行该请求同样失败。
错误信息
Promise{<rejected>: TypeError: Failed to Fetch at eval (eval at executeScript (:445:16), <anonymous>:3:37)..}
源代码
from selenium import webdriver from selenium.webdriver.chrome.options import Options import datetime import json from selenium.webdriver import Keys, ActionChains from selenium.webdriver.common.by import By from selenium import webdriver from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC chrome_options = Options() #chrome_options.add_argument('--headless') chrome_options.add_argument('--no-sandbox') chrome_options.add_argument('--disable-dev-shm-usage') #chrome_options.add_experimental_option('detach', True) chrome_options.add_argument('--user-data-dir=https://replit.com/@KhaelaFortunela/autovoter#Profile%202') chrome_options.add_argument("--auto-open-devtools-for-tabs") driver = webdriver.Chrome(options=chrome_options) driver.get("https://twitter.com/home") payload = '{"variables":{"tweet_text":"BRI sebagai BUMN mewujudkan komitmen untuk menciptakan lapangan pekerjaan yg bersifat berkelanjutan seperti Agen BRILink, serta penyaluran kredit KUR sebagai modal usaha yang diharapkan dapat memajukan ekonomi rakyat \n#TransformasiBRI127 #ROSBYWANI","media":{"media_entities":[],"possibly_sensitive":false},"withDownvotePerspective":false,"withReactionsMetadata":false,"withReactionsPerspective":false,"withSuperFollowsTweetFields":true,"withSuperFollowsUserFields":true,"semantic_annotation_ids":[],"dark_request":false},"features":{"view_counts_public_visibility_enabled":false,"tweetypie_unmention_optimization_enabled":true,"responsive_web_uc_gql_enabled":true,"vibe_api_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"interactive_text_enabled":true,"responsive_web_text_conversations_enabled":false,"responsive_web_twitter_blue_verified_badge_is_enabled":true,"verified_phone_label_enabled":false,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":false,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_enhance_cards_enabled":true},"queryId":"sqNNr7rKZwnDQZkIiyvcrA"}' fetch_req = '{"headers": {"accept": "*/*","accept-language": "en-US,en;q=0.9","authorization": "Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA","content-type": "application/json","sec-fetch-dest": "empty","sec-fetch-mode": "cors","sec-fetch-site": "same-origin","x-csrf-token": "dc535379510138f59a330ed89961a6ef05f26b1d98eaf397c4b6999cdbbea319303dd54ec820339920d848cf5f000da1f15fa3434bf910d8e8d2d61aa2f9638f7c2beb52d000108c01e6dc772b0cf98c","x-twitter-active-user": "yes","x-twitter-auth-type": "OAuth2Session","x-twitter-client-language": "en"},"referrer": "https://mobile.twitter.com/compose/tweet","referrerPolicy": "strict-origin-when-cross-origin","body": "payload","method": "POST", "mode": "cors","credentials": "include"}' #while True: for i in range(10): t = datetime.datetime.now() time_now = t.strftime("%X") y = json.loads(payload, strict=False) y['variables']['tweet_text'] = time_now + " " + y['variables']['tweet_text'] new_payload = json.dumps(y) z = json.loads(fetch_req, strict=False) z['body'] = new_payload new_fetch_req = json.dumps(z) text = 'console.log(' + 'fetch("https://mobile.twitter.com/i/api/graphql/sqNNr7rKZwnDQZkIiyvcrA/CreateTweet"' + ',' + new_fetch_req + '))' driver.execute_script(text)
原因分析
- 静态请求头失效:硬编码的
x-csrf-token、authorization等头信息是动态生成的,Twitter会定期更新这些值,且每个会话的CSRF Token唯一,固定值会被服务器判定为非法请求。 - 用户数据目录配置错误:
--user-data-dir参数需要本地文件系统路径,你传入的是在线URL,导致浏览器无法加载有效登录会话,请求缺少合法凭证。 - 请求代码拼接语法错误:手动拼接
execute_script的fetch字符串时,JSON字符串中的引号未正确转义,浏览器执行时会出现语法解析错误。 - 页面与API环境不匹配:打开的是桌面端Twitter页面,但请求的是移动端API端点,环境不一致可能触发安全检测。
解决方法
- 动态获取请求头:通过Selenium从当前页面的Cookie或请求头中提取最新的
x-csrf-token和authorization值,不要硬编码。 - 修正用户数据目录:使用本地合法的用户数据目录路径,或在代码中模拟登录流程,确保会话有效。
- 正确构造执行代码:避免手动拼接字符串,直接将请求参数作为Python对象传入
execute_script,让Selenium自动处理序列化:# 替换原有的text拼接和execute_script代码 driver.execute_script(""" fetch(arguments[0], arguments[1]) """, "https://mobile.twitter.com/i/api/graphql/sqNNr7rKZwnDQZkIiyvcrA/CreateTweet", z) - 统一页面与API环境:要么打开移动端Twitter页面,要么使用桌面端对应的API端点,保持请求来源与目标环境一致。
内容的提问来源于stack exchange,提问作者Khaela Fortunela
相关产品推荐
相关产品推荐

