祝大家五一假期快樂!
最近推特加了逆向,頻繁出現404,無法正常抓取數據,這里給出推特逆向的思路及代碼,供大家參考學習!
本文將介紹如何使用 Python 模擬請求 Twitter 的 GraphQL 接口,結合 requests
、BeautifulSoup
和自定義的 x-client-transaction-id
參數,成功獲取搜索結果中的 timeline 數據。適合具備一定 Python 基礎的開發者或對 Web 爬蟲感興趣的同學。
一、背景介紹
眾所周知,Twitter(現 X)并沒有開放完整的搜索接口給普通用戶使用。如果你不是開發者賬號,或者沒有獲得 Twitter API v2 的高級權限,就很難通過官方 API 獲取搜索結果。
但實際上,Twitter 的 Web 前端使用的是 GraphQL 接口進行數據交互。我們可以通過分析請求,手動構造這些請求并獲取數據。
二、核心技術棧
-
requests
:用于發起 HTTP 請求 -
bs4
(BeautifulSoup
):用于解析 Twitter 首頁 HTML,輔助構造 client_transaction_id -
json
:構造 GraphQL 請求參數 -
loguru
:用于日志記錄 -
自定義模塊
ClientTransaction
:用于生成 Twitter 的x-client-transaction-id
三、關鍵參數獲取
為了成功模擬 Twitter 請求,我們需要準備以下關鍵參數:
-
authorization
Token:用于通過認證。 -
Cookie
:用于維持會話,尤其是ct0
和auth_token
是必要的。 -
x-client-transaction-id
:是防爬關鍵參數,通過訪問首頁解析獲得。
四、代碼
import bs4
import requests
import time
from decryption.transaction import ClientTransaction
from loguru import logger
import json
# 設置 cookie 和 authorization(需自己抓包獲取)
twitter_cookie = '...你的cookie...'
authorization = "Bearer ...你的token..."
# 提取 ct0
xCsrfToken = ""
for part in twitter_cookie.split(";"):if part.strip().startswith("ct0="):xCsrfToken = part.strip().split("=", 1)[1]break
def get_cursor(dataJson):instructions = dataJson.get('data', {}).get('search_by_raw_query', {}).get('search_timeline', {}).get('timeline', {}).get('instructions', [])entries = []cursor = Nonefor ins in instructions:if ins.get('type') == "TimelineAddEntries":entries = ins.get('entries', [])for ent in entries:content = ent.get('content', {})if content.get('cursorType') == 'Bottom':cursor = content.get('value')breakreturn cursor, entries
cursor = ''
page = 1while True:url = "https://twitter.com"resp = requests.get(url, headers={"User-Agent": "..."})response = bs4.BeautifulSoup(resp.content, "lxml")ctreq = ClientTransaction(home_page_response=response)xClientTransactionId = ctreq.generate_transaction_id(method="GET",path="/i/api/graphql/AIdc203rPpK_k_2KWSdm7g/SearchTimeline")url = "https://x.com/i/api/graphql/AIdc203rPpK_k_2KWSdm7g/SearchTimeline"headers = {"authorization": authorization,"x-client-transaction-id": xClientTransactionId,"x-csrf-token": xCsrfToken,"x-twitter-auth-type": "OAuth2Session","x-twitter-active-user": "yes","x-twitter-client-language": "zh-cn","Cookie": twitter_cookie,"content-type": "application/json"}variables = {"rawQuery": "feed","count": 20,"querySource": "typed_query","product": "Top",}if cursor:variables["cursor"] = cursorparams = {"variables": json.dumps(variables, separators=(",", ":")),"features": json.dumps({"rweb_video_screen_enabled": False,"profile_label_improvements_pcf_label_in_post_enabled": True,# ...省略部分參數})}response = requests.get(url, headers=headers, params=params)logger.info(f"頁數:{page},狀態碼:{response.status_code}")if response.status_code == 404:logger.warning("頁面未找到,重試...")continuereq_data = response.json()cursor, entries = get_cursor(req_data)for entry in entries:logger.info(entry)time.sleep(3)page += 1
五、運行效果展示
六、注意事項
-
防止封號:建議不要頻繁請求,設置合理的
sleep
(如 3~5 秒)。 -
cookie 有效期:
auth_token
和ct0
是有時效性的,需要定期更新。
七、總結
通過對 Twitter Web 接口的逆向分析,我們可以在不依賴官方 API 的情況下實現搜索結果的抓取。當然,這種方式存在一定的穩定性和合規風險,建議僅用于學習研究。如需幫助可以聯系:zx_luckfe