web-dev-qa-db-fra.com

API Twitter - obtenez des tweets avec un identifiant spécifique

J'ai une liste d'ID de Tweet pour lesquels je voudrais télécharger leur contenu texte. Y a-t-il une solution simple pour le faire, de préférence via un script Python? J'ai jeté un œil à d'autres bibliothèques comme Tweepy et les choses ne semblent pas fonctionner si simple, et les télécharger manuellement est terminé de la question puisque ma liste est très longue.

21
Crista23

Vous pouvez accéder à des tweets spécifiques par leur identifiant avec la route statuses/show/:id API . La plupart des bibliothèques Python Twitter suivent exactement les mêmes modèles ou proposent des noms "conviviaux" pour les méthodes.

Par exemple, Twython propose plusieurs méthodes show_*, Y compris Twython.show_status() qui vous permet de charger des tweets spécifiques:

CONSUMER_KEY = "<consumer key>"
CONSUMER_SECRET = "<consumer secret>"
OAUTH_TOKEN = "<application key>"
OAUTH_TOKEN_SECRET = "<application secret"
Twitter = Twython(
    CONSUMER_KEY, CONSUMER_SECRET,
    OAUTH_TOKEN, OAUTH_TOKEN_SECRET)

Tweet = Twitter.show_status(id=id_of_Tweet)
print(Tweet['text'])

et le dictionnaire retourné suit la définition d'objet Tweet donnée par l'API.

La bibliothèque tweepy utilise tweepy.get_status() :

auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
auth.set_access_token(OAUTH_TOKEN, OAUTH_TOKEN_SECRET)
api = tweepy.API(auth)

Tweet = api.get_status(id_of_Tweet)
print(Tweet.text)

où il renvoie un objet légèrement plus riche, mais ses attributs reflètent à nouveau l'API publiée.

35
Martijn Pieters

Partager mon travail qui a été largement accéléré par les réponses précédentes (merci). Ce script Python 2.7 récupère le texte des identifiants Tweet stockés dans un fichier. Ajustez get_Tweet_id () pour votre format de données d'entrée; original configuré pour les données à https://github.com/mdredze/Twitter_sandy

Mise à jour d'avril 2018: réponse tardive au rapport de bogue @someone (merci). Ce script ne supprime plus tous les 100 ID de Tweet (c'était mon bug). Veuillez noter que si un Tweet n'est pas disponible pour une raison quelconque, la récupération groupée l'ignore en silence. Le script avertit maintenant si la taille de la réponse est différente de la taille de la demande.

'''
Gets text content for Tweet IDs
'''

# standard
from __future__ import print_function
import getopt
import logging
import os
import sys
# import traceback
# third-party: `pip install tweepy`
import tweepy

# global logger level is configured in main()
Logger = None

# Generate your own at https://apps.Twitter.com/app
CONSUMER_KEY = 'Consumer Key (API key)'
CONSUMER_SECRET = 'Consumer Secret (API Secret)'
OAUTH_TOKEN = 'Access Token'
OAUTH_TOKEN_SECRET = 'Access Token Secret'

# batch size depends on Twitter limit, 100 at this time
batch_size=100

def get_Tweet_id(line):
    '''
    Extracts and returns Tweet ID from a line in the input.
    '''
    (tagid,_timestamp,_sandyflag) = line.split('\t')
    (_tag, _search, Tweet_id) = tagid.split(':')
    return Tweet_id

def get_tweets_single(twapi, idfilepath):
    '''
    Fetches content for Tweet IDs in a file one at a time,
    which means a ton of HTTPS requests, so NOT recommended.

    `twapi`: Initialized, authorized API object from Tweepy
    `idfilepath`: Path to file containing IDs
    '''
    # process IDs from the file
    with open(idfilepath, 'rb') as idfile:
        for line in idfile:
            Tweet_id = get_Tweet_id(line)
            Logger.debug('get_tweets_single: fetching Tweet for ID %s', Tweet_id)
            try:
                Tweet = twapi.get_status(Tweet_id)
                print('%s,%s' % (Tweet_id, Tweet.text.encode('UTF-8')))
            except tweepy.TweepError as te:
                Logger.warn('get_tweets_single: failed to get Tweet ID %s: %s', Tweet_id, te.message)
                # traceback.print_exc(file=sys.stderr)
        # for
    # with

def get_Tweet_list(twapi, idlist):
    '''
    Invokes bulk lookup method.
    Raises an exception if rate limit is exceeded.
    '''
    # fetch as little metadata as possible
    tweets = twapi.statuses_lookup(id_=idlist, include_entities=False, trim_user=True)
    if len(idlist) != len(tweets):
        Logger.warn('get_Tweet_list: unexpected response size %d, expected %d', len(tweets), len(idlist))
    for Tweet in tweets:
        print('%s,%s' % (Tweet.id, Tweet.text.encode('UTF-8')))

def get_tweets_bulk(twapi, idfilepath):
    '''
    Fetches content for Tweet IDs in a file using bulk request method,
    which vastly reduces number of HTTPS requests compared to above;
    however, it does not warn about IDs that yield no Tweet.

    `twapi`: Initialized, authorized API object from Tweepy
    `idfilepath`: Path to file containing IDs
    '''    
    # process IDs from the file
    Tweet_ids = list()
    with open(idfilepath, 'rb') as idfile:
        for line in idfile:
            Tweet_id = get_Tweet_id(line)
            Logger.debug('Enqueing Tweet ID %s', Tweet_id)
            Tweet_ids.append(Tweet_id)
            # API limits batch size
            if len(Tweet_ids) == batch_size:
                Logger.debug('get_tweets_bulk: fetching batch of size %d', batch_size)
                get_Tweet_list(twapi, Tweet_ids)
                Tweet_ids = list()
    # process remainder
    if len(Tweet_ids) > 0:
        Logger.debug('get_tweets_bulk: fetching last batch of size %d', len(Tweet_ids))
        get_Tweet_list(twapi, Tweet_ids)

def usage():
    print('Usage: get_tweets_by_id.py [options] file')
    print('    -s (single) makes one HTTPS request per Tweet ID')
    print('    -v (verbose) enables detailed logging')
    sys.exit()

def main(args):
    logging.basicConfig(level=logging.WARN)
    global Logger
    Logger = logging.getLogger('get_tweets_by_id')
    bulk = True
    try:
        opts, args = getopt.getopt(args, 'sv')
    except getopt.GetoptError:
        usage()
    for opt, _optarg in opts:
        if opt in ('-s'):
            bulk = False
        Elif opt in ('-v'):
            Logger.setLevel(logging.DEBUG)
            Logger.debug("main: verbose mode on")
        else:
            usage()
    if len(args) != 1:
        usage()
    idfile = args[0]
    if not os.path.isfile(idfile):
        print('Not found or not a file: %s' % idfile, file=sys.stderr)
        usage()

    # connect to Twitter
    auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
    auth.set_access_token(OAUTH_TOKEN, OAUTH_TOKEN_SECRET)
    api = tweepy.API(auth)

    # hydrate Tweet IDs
    if bulk:
        get_tweets_bulk(api, idfile)
    else:
        get_tweets_single(api, idfile)

if __name__ == '__main__':
    main(sys.argv[1:])
7
chrisinmtown

Je n'ai pas assez de réputation pour ajouter un commentaire réel, malheureusement c'est la voie à suivre:

J'ai trouvé un bug et une chose étrange dans la réponse de chrisinmtown:

Chaque 100e Tweet sera ignoré en raison du bug. Voici une solution simple:

        if len(Tweet_ids) < 100:
            Tweet_ids.append(Tweet_id)
        else:
            Tweet_ids.append(Tweet_id)
            get_Tweet_list(twapi, Tweet_ids)
            Tweet_ids = list()

L'utilisation est meilleure car elle fonctionne même au-delà de la limite de taux.

api = tweepy.API(auth_handler=auth, wait_on_rate_limit=True, wait_on_rate_limit_notify=True)
5
Someone

Vous pouvez accéder aux tweets en bloc (jusqu'à 100 à la fois) avec le point de terminaison état/recherche: https://dev.Twitter.com/rest/reference/get/statuses/lookup

5
verdverm