LiesAuer's Blog
关于
归档
友链
猫咪
RSS
后台
切换模式
返回顶部
首页
说说
日常
开发
游戏
资源
虚拟货币
LiesAuer's Blog
首页
说说
日常
开发
游戏
资源
虚拟货币
关于
归档
友链
猫咪
RSS
后台
Twitter推文监控API
开发
·
虚拟货币
·
2022-12-17
LiesAuer
## 阅读前须知 **本文所提及的所有接口均非官方开放API,而是直接从网页端抓包而来,可能存在以下限制及风险!!!** 1. `Cookie` `CSRF Token`有效时间未知,可能会不定期失效或请求失败 2. 大多数看似无用的参数、Cookie已被清理,并未附带在请求内,可能会被识别成脚本或机器人请求 3. 监控大量账号效率低下(每个账号都要单独发送请求获取数据,无法做到类似官方的流式订阅) 4. 不确定是否有封号风险 5. ~~不确定请求频率风控策略~~([Rate limits | Docs | Twitter Developer Platform](https://developer.twitter.com/en/docs/twitter-api/rate-limits "Rate limits | Docs | Twitter Developer Platform")) ## 获取必需参数、Cookie 打开开发者面板并打开Web端Twitter`https://mobile.twitter.com/home`,找到以下请求(或直接搜索`HomeTimeline`): ``` https://mobile.twitter.com/i/api/graphql/XXXXXXXXXX/HomeTimeline ``` ### Bearer Token `authorization`请求头就是了。 ### Cookie `ct0` `auth_token` `cookie`请求头里把这两个找出来即可,别的不需要。 ### CSRF Token `x-csrf-token`请求头就是了,实测`CSRF Token`可重用。 ## 请求API url中的`XXXXXXXXXX`是一串未知字符,可从控制台网络中找到,这是会变的,且每个api的都不同,但同一个api一直用死一个好像也没问题,将`$XXX$`替换为真实的参数即可,请求中的`variables` `features`参数都是JSON文本,把它们当成普通内容将其正常的urlencode传递到url即可,无需任何额外处理。 ### 用户名转用户ID ``` GET https://mobile.twitter.com/i/api/graphql/XXXXXXXXXX/UserByScreenName 请求头: authorization: $BEARER_TOKEN$ content-type: application/json x-csrf-token: $CSRF_TOKEN$ x-twitter-active-user: yes x-twitter-auth-type: OAuth2Session x-twitter-client-language: zh-cn 请求Cookie: ct0: $CT0$ auth_token: $AUTH_TOKEN$ 请求参数: variables: {"screen_name":"$USER_NAME$","withSafetyModeUserFields":true,"withSuperFollowsUserFields":true} features: {"responsive_web_twitter_blue_verified_badge_is_enabled":true,"verified_phone_label_enabled":false,"responsive_web_twitter_blue_new_verification_copy_is_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true} ``` 返回数据格式如下(仅包含获取用户ID的必需结构): **注意:`rest_id`才是用户ID** ```typescript interface UserIdApi { data: { user: { result: { id: string, legacy: { name: string, screen_name: string, followers_count: number, }, rest_id: string, }, }, }, } ``` ### 推文列表 ``` GET https://mobile.twitter.com/i/api/graphql/XXXXXXXXXX/UserTweets 请求头: authorization: $BEARER_TOKEN$ content-type: application/json x-csrf-token: $CSRF_TOKEN$ x-twitter-active-user: yes x-twitter-auth-type: OAuth2Session x-twitter-client-language: zh-cn 请求Cookie: ct0: $CT0$ auth_token: $AUTH_TOKEN$ 请求参数: variables: {"userId":"$USER_ID$","count":40,"includePromotedContent":true,"withQuickPromoteEligibilityTweetFields":true,"withSuperFollowsUserFields":true,"withDownvotePerspective":false,"withReactionsMetadata":false,"withReactionsPerspective":false,"withSuperFollowsTweetFields":true,"withVoice":true,"withV2Timeline":true} features: {"responsive_web_twitter_blue_verified_badge_is_enabled":true,"verified_phone_label_enabled":false,"responsive_web_graphql_timeline_navigation_enabled":true,"view_counts_public_visibility_enabled":false,"view_counts_everywhere_api_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,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":false,"interactive_text_enabled":true,"responsive_web_text_conversations_enabled":false,"responsive_web_enhance_cards_enabled":true} ``` 返回数据格式如下(仅包含获取推文的必需结构): **`full_text`就是推文内容** **`retweeted_status_result`是嵌套结构,当回复推文的时候就有,正常推文不会有,被回复人ID是`user_id_str`,被回复人的用户名可在`entities.user_mentions`中查到,回复的推文一定要从这里取,在第一级的`full_text`取是被截断后的内容,并不完整** ```typescript type tweet_results = { result: { rest_id: string, legacy: { created_at: string, full_text: string, user_id_str: string, entities?: { user_mentions: { id_str: string, name: string, screen_name: string, }[], }, retweeted_status_result?: tweet_results, }, }, } type UserTweetsApiInstructions = { type: "TimelineClearCache" | "TimelineAddEntries" | "TimelinePinEntry", entries?: { entryId: string, sortIndex: string, content: { entryType: "TimelineTimelineItem" | "TimelineTimelineCursor" | "TimelineTimelineModule", itemContent?: { itemType: string, tweet_results: tweet_results, }, items?: { item: { itemContent?: { itemType: string, tweet_results: tweet_results, }, }, }[], metadata?: { conversationMetadata: { allTweetIds: string[], }, }, clientEventInfo?: { component: "suggest_ranked_organic_tweet" | "suggest_who_to_follow", }, value?: string, cursorType?: "Top" | "Bottom", }, }[], entry?: { entryId: string, sortIndex: string, content: { entryType: "TimelineTimelineItem", itemContent?: { itemType: string, tweet_results: tweet_results, }, value?: string, cursorType?: "Top" | "Bottom", }, }, }[] interface UserTweetsApi { data: { user: { result: { timeline_v2: { timeline: { instructions: UserTweetsApiInstructions, }, }, }, }, }, } ``` ### 更多推文 在获取到首页40条推文后,返回的数据还包含了当前页的最后推文游标,搜索`TimelineTimelineCursor`字段,并找到`cursorType`为`Bottom`的内容,其`value`就是当前页的最后推文的游标,并将其加入到`variables`参数的`cursor`字段中即可获取后面分页内容。 此时`variables`内容如下: ```json {"userId":"$USER_ID$","count":40,"cursor":"$BOTTOM_CURSOR$","includePromotedContent":true,"withQuickPromoteEligibilityTweetFields":true,"withSuperFollowsUserFields":true,"withDownvotePerspective":false,"withReactionsMetadata":false,"withReactionsPerspective":false,"withSuperFollowsTweetFields":true,"withVoice":true,"withV2Timeline":true} ``` ### 成品展示 
Twitter
推特
推文监控
鲸鱼监控
取消回复
提交评论
brayn
05-12
回复
hello,能否公布下这个微信公众号,以及请问怎么实现订阅推特新增关注?
LiesAuer
(作者)
05-12
回复
@brayn
你好,这个公众号是不对外开放的。
热门文章
HumanMod - 免费的集N多功能于一身的HFF(人类一败涂地)插件
记抖音爬虫中所遇到的坑
设置网易邮箱大师为Win10默认邮件客户端
微信表情包工具【2023/05/04】更新
更改TLY本地代理端口
让Tauri前端部分调试如调试常规Web项目般丝滑
使用 v2rayN + SSTap 对 Win10 + WSL2 进行超简单易用的科学上网设置
最新评论
dw673j: 好顶赞!!!!
1: 爹!
Jekanius: Hello, I implemented such a mech...
Jekanius: I need you help.
Jekanius: Is it working now?
任情随缘: 很多站长卖的站和老域名大部分都到了这些搞灰产的手里。
滚石: 赞
关于站长
广东 佛山
liesauer#liesauer.net
LiesAuer
粤ICP备16094588号-1
Theme
Jasmine
by
Kent Liao
hello,能否公布下这个微信公众号,以及请问怎么实现订阅推特新增关注?
你好,这个公众号是不对外开放的。