新的 Twitter v2 API 几周前刚刚发布,所以这可能只是文档尚未完成的问题。
我想做的是在最近的推文中搜索“小狗”,并返回所有附加了某种媒体的推文。然而,当我在 Postman 中运行此搜索时,并非所有返回的推文都有
attachments.media_keys
。我注意到那些没有 attachments.media_keys
的推文的文本以省略号 ...
结尾。据我所知,在 v1.1 API 中,这个问题是通过在查询参数中指定 tweet_mode=extended
或 tweet.fields=extended_tweet
来解决的。然而,这些似乎在 v2 API 中不起作用,而且我还没有看到任何有关获取推文全文(以及相关附件)的文档。有谁知道在 v2 中如何做到这一点?
我的邮递员查询网址:“https://api.twitter.com/2/tweets/search/recent?query=has:media puppies&tweet.fields=attachments&expansions=attachments.media_keys&media.fields=duration_ms,height,media_key,preview_image_url, public_metrics,类型,url,宽度”
在我的应用程序中,我使用 Node.js Axios 来执行查询:
var axios = require('axios');
var config = {
method: 'get',
url: 'https://api.twitter.com/2/tweets/search/recent?query=has:media puppies&tweet.fields=attachments&expansions=attachments.media_keys&media.fields=duration_ms,height,media_key,preview_image_url,public_metrics,type,url,width',
headers: {
'Authorization': 'Bearer {{my berarer token}}',
}
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
截至 2021 年 7 月,这个“问题”或奇怪的行为肯定与转发有关。
为了在获取用户最近的推文的同时获取转发的全文,我做了以下技巧:
首先,我收到关注 docs 的用户的最新推文:
curl "https://api.twitter.com/2/users/2244994945/tweets?expansions=attachments.poll_ids,attachments.media_keys,author_id,entities.mentions.username,geo.place_id,in_reply_to_user_id,referenced_tweets.id,referenced_tweets.id.author_id&tweet.fields=attachments,author_id,context_annotations,conversation_id,created_at,entities,geo,id,in_reply_to_user_id,lang,possibly_sensitive,public_metrics,referenced_tweets,reply_settings,source,text,withheld&user.fields=created_at,description,entities,id,location,name,pinned_tweet_id,profile_image_url,protected,public_metrics,url,username,verified,withheld&place.fields=contained_within,country,country_code,full_name,geo,id,name,place_type&poll.fields=duration_minutes,end_datetime,id,options,voting_status&media.fields=duration_ms,height,media_key,preview_image_url,type,url,width,public_metrics,non_public_metrics,organic_metrics,promoted_metrics&max_results=5" -H "Authorization: Bearer $BEARER_TOKEN"
这是一个全字段查询(并非所有字段都是必需的),但需要在返回的 JSON 数据的结构中获取
['includes']['tweets']
。您必须在此处查找转发的全文 - 它位于:['includes']['tweets'][0..n]['text]
,而所有最近的推文(和转发)都可以在 ['data'][0..n]['text']
找到。
然后您必须将
['data']
中的缩短转发与 ['includes']['tweets']
中的转发进行匹配。我使用 ['data'][n]['referenced_tweets'][0]['id']
来完成此操作,它应该与 ['includes']['tweets'][m]['id]
匹配。其中 n
和 m
是一些索引。
为了100%安全,您可以检查
['data'][n]['referenced_tweets'][0]['id']
是否具有匹配的键/值对:type: retweet
(表明这实际上是转发参考),但对我来说,0
索引适用于所有检查的情况,所以不是为了让事情变得更复杂,我暂时就这样了:)
如果这听起来很复杂,只需转储整个解析的 JSON 和所有推文并检查数据的结构。
import requests
import urllib.parse
import json
keyword_to_search = 'BMW Cars'
safe_string = urllib.parse.quote_plus(keyword_to_search)
url = "https://api.twitter.com/2/tweets/search/recent?expansions=attachments.poll_ids,attachments.media_keys,author_id,entities.mentions.username,geo.place_id,in_reply_to_user_id,referenced_tweets.id,referenced_tweets.id.author_id&tweet.fields=attachments,author_id,context_annotations,conversation_id,created_at,entities,geo,id,in_reply_to_user_id,lang,possibly_sensitive,public_metrics,referenced_tweets,reply_settings,source,text,withheld&user.fields=created_at,description,entities,id,location,name,pinned_tweet_id,profile_image_url,protected,public_metrics,url,username,verified,withheld&place.fields=contained_within,country,country_code,full_name,geo,id,name,place_type&poll.fields=duration_minutes,end_datetime,id,options,voting_status&media.fields=duration_ms,height,media_key,preview_image_url,type,url,width,public_metrics,non_public_metrics,organic_metrics,promoted_metrics&max_results=10"
payload = f'query={safe_string}'
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer TOKEN_YOU_GOT_FROM_TWITTER',
}
response = requests.request("GET", url, headers=headers, data=payload)
parsed_response = json.loads(response.text)
outputs = []
for tweet in parsed_response['data']:
id = tweet['id']
text = tweet['text']
# detect if it is retweeted
retweet_id = None
if 'referenced_tweets' in tweet:
for referenced_tweet in tweet['referenced_tweets']:
if referenced_tweet['type']=='retweeted':
retweet_id = referenced_tweet['id']
if retweet_id is not None:
if 'includes' in parsed_response and 'tweets' in parsed_response['includes']:
for item in parsed_response['includes']['tweets']:
if item['id'] == retweet_id:
text = item['text']
outputs.append({
'tweet_id': id,
'tweet_text': text
})
outputs