I'm following a tutorial about analyzing twitter data. I'm wondering why I keep getting a syntax error on line 44: except BaseException as e:
from tweepy import API
from tweepy import Cursor
from tweepy.streaming import StreamListener
from tweepy import OAuthHandler
from tweepy import Stream
import twitter_credentials
#TWITTER AUTHENTICATOR
class TwitterAuthenticator():
def authenticate_twitter_app(self):
auth = OAuthHandler(twitter_credentials.CONSUMER_KEY, twitter_credentials.CONSUMER_SECRET)
auth.set_access_token(twitter_credentials.ACCESS_TOKEN, twitter_credentials.ACCESS_TOKEN_SECRET)
return auth
#TWITTER STREAMER
class TwitterStreamer():
#Class for streaming and processing live tweets
def __init__(self):
self.twitter_authenticator = TwitterAuthenticator()
def stream_tweets(self, fetched_tweets_filename, hash_tag_list):
#This handles Twitter authentication and connection to the Twitter streaming API
listener = TwitterListener()
auth = self.twitter_authenticator.authenticate_twitter_app()
stream = Stream(auth, listener)
stream.filter(track=hash_tag_list)
class TwitterListener(StreamListener):
#Basic listener class that just prints received tweets to stdout
def __init__(self, fetched_tweets_filename):
self.fetched_tweets_filename = fetched_tweets_filename
def on_data(self, data):
try:
print(data)
with open(self.fetched_tweets_filename, 'a') as tf:
tf.write(data)
return True
except BaseException as e:
print('Error on_data %s' % str(e))
return True
def on_error(self, status):
print(status)
if __name__ == '__main__':
hash_tag_list['kevin durant', 'steph curry', 'clippers']
fetched_tweets_filename = 'tweets.json'
twitter_streamer = TwitterStreamer()
twitter_streamer.stream_tweets(fetched_tweets_filename, hash_tag_list)
Your except is indented too much. Should be on the same level as try (in on_data()) and the code in except should be indented the same.
Btw said function is written wrong. There are potential cases where it returns nothing. You should have at least return False added at the end of function body.
Except should be indented as try, so try the following
def on_data(self, data):
try:
print(data)
with open(self.fetched_tweets_filename, 'a') as tf:
tf.write(data)
return True
except BaseException as e:
print('Error on_data %s' % str(e))
return True
Related
I've been following the tutorial available at realpython to try and create a twitter bot that retweets a specific user based on keywords within their tweet. By using the follow and track parameters, I should be able to retweet only those tweets that contain goal AND assist but the listener seems to retweets all tweets that contain these keywords not the specific user.
#!/usr/bin/env python
# tweepy-bots/bots/retweet.py
import tweepy
import logging
from config import create_api
import json
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger()
class RetweetListener(tweepy.StreamListener):
def __init__(self, api):
self.api = api
self.me = api.me()
def on_status(self, tweet):
logger.info(f"Processing tweet id {tweet.id}")
if tweet.in_reply_to_status_id is not None or \
tweet.user.id == self.me.id:
# This tweet is a reply or I'm its author so, ignore it
return
if not tweet.retweeted:
# if 'GOAL' and 'ASSIST' in tweet.full_text:
# Retweet, since we have not retweeted it yet
try:
tweet.retweet()
except Exception as e:
logger.error("Error on fav and retweet", exc_info=True)
def on_error(self, status):
logger.error(status)
def main(keywords):
api = create_api()
tweets_listener = RetweetListener(api)
stream = tweepy.Stream(api.auth, tweets_listener)
stream.filter(follow=['761568335138058240'],
track=keywords, languages=["en"])
if __name__ == "__main__":
main(["Goal Assist"])
Posting my own answer based on how I hacked it together, not sure if it's the best method but it works.
class RetweetListener(tweepy.StreamListener):
def __init__(self, api):
self.api = api
self.me = api.me()
def on_status(self, tweet):
logger.info(f"Processing tweet id {tweet.id}")
if tweet.in_reply_to_status_id is not None or \
tweet.user.id == self.me.id:
# This tweet is a reply or I'm its author so, ignore it
return
if not tweet.retweeted:
if 'Goal -' and 'Assist -' in tweet.text:
try:
# Retweet, since we have not retweeted it yet
tweet.retweet()
except Exception as e:
logger.error("Error on fav and retweet", exc_info=True)
def on_error(self, status):
logger.error(status)
Am doing a project to find top 10 trending topics or hashtags on Twitter. Am creating a class with the code below:
class TweetsListener(StreamListener):
def __init__(self, csocket):
self.client_socket = csocket
def on_data(self, data):
try:
msg = json.loads( data )
print(msg['user']['screen_name'].encode('utf-8'))
return True
except BaseException as e:
print("Error on_data: %s" % str(e))
return True
def on_error(self, status):
print(status)
return True
Below is the code for sending data:
def sendData(c_socket):
auth = OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_secret)
twitter_stream = Stream(auth, TweetsListener(c_socket))
twitter_stream.filter(track=['india']
Here twitter_stream.filter is filtering messages with tag India. I want to get all the messages from Twitter. In short, I do not want a filter to be applied. Is there a way to do the same?
Any help appreciated.
- P.S : Novice in Spark streaming and PySpark
Twitter now offers a sample stream: https://developer.twitter.com/en/docs/tweets/sample-realtime/overview/GET_statuse_sample.html
It's fairly new so I'm not sure if the wrappers (looks like you're using Tweepy) have implemented it yet, but it shouldn't be hard to interface with.
I'm using this code to capture the content of live streams using the 'text' identifier which basically captures the actual tweet text from Tweepys streaming capture function. It seems to be working for the most part, but I also receive the occasional "Not Working" message as a result of the exception in the code when I run the script (it happen maybe once every 10 10 seconds or so when I search a term that is trending heavily). The output file still capture many tweets despite this. I was wondering if anyone knew what could be causing this exception, as I'm worried I may be missing the occasional tweet as a result of it.
class MyListener(StreamListener):
def on_data(self, data):
try:
with open('python.json', 'a') as f:
datadict = json.loads(data)
f.write(datadict['text'])
return True
except BaseException as e:
print("Not Working")
return True
def on_error(self, status):
print(status)
return True
twitter_stream = Stream(auth, MyListener())
twitter_stream.filter(track=['Search_term_go's_here'])
You might have accessed a tweet that is private. You can check the exception by trying this:
except tweepy.TweepError as e:
print e
print type(e)
print e.__dict__
print e.reason
print type(e.reason)
very new to this but I need twitter data from the area of London from the streaming api service
This is the code i'm running
from tweepy import Stream
from tweepy.streaming import StreamListener
class MyListener(StreamListener):
def on_data(self, data):
try:
with open('london.json', 'a') as f:
f.write(data)
return True
except BaseException as e:
print("Error on_data: %s" % str(e))
return True
def on_error(self, status):
print(status)
return True
twitter_stream = Stream(auth, MyListener())
twitter_stream.filter(locations=['0.28,51.23,0.25,51.68'])
This is the error I keep getting
TweepError: Wrong number of locations points, it has to be a multiple of 4
I may be getting the bounding box wrong but am unsure how to find it for London??
Thanks
I am using the following code to stream direct messages received by my Twitter account -:
from tweepy import Stream
from tweepy import OAuthHandler
from tweepy import API
from tweepy.streaming import StreamListener
# These values are appropriately filled in the code
consumer_key = ""
consumer_secret = ""
access_token = ""
access_token_secret = ""
class StdOutListener( StreamListener ):
def __init__( self ):
self.tweetCount = 0
def on_connect( self ):
print("Connection established!!")
def on_disconnect( self, notice ):
print("Connection lost!! : ", notice)
def on_data( self, status ):
print("Entered on_data()")
print(status, flush = True)
return True
def on_direct_message( self, status ):
print("Entered on_direct_message()")
try:
print(status, flush = True)
return True
except BaseException as e:
print("Failed on_direct_message()", str(e))
def on_error( self, status ):
print(status)
def main():
try:
auth = OAuthHandler(consumer_key, consumer_secret)
auth.secure = True
auth.set_access_token(access_token, access_token_secret)
api = API(auth)
# If the authentication was successful, you should
# see the name of the account print out
print(api.me().name)
stream = Stream(auth, StdOutListener())
stream.userstream()
except BaseException as e:
print("Error in main()", e)
if __name__ == '__main__':
main()
I am able to get my name printed as well as the "Connection established!" message.
But whenever I send a direct message to my own profile from my friend's profile, no method is called.
Although, whenever I tweet something from my profile, it is printed correctly by the program.
Me and my friend both follow each other on Twitter, so there shouldn't be any problems with the direct message permissions.
What is the proper way to do it ?
Also, if it cannot be done in Tweepy at all, I am ready to use any other Python library.
I am using Tweepy 3.3.0 and Python 3.4 on Windows 7.
The code provided in the question is indeed correct.
The problem was that I had forgotten to regenerate the access token and secret after changing my application permissions to "Read, write and direct messages".
Note: The direct messages arrive in the on_data() method rather than the on_direct_message() method.
Another solution is to not override the on_data method. That is how I got your code example to work in my case.
The on_data method of tweepy.streaming.StreamListener object contains all the json data handling and calling of other methods, like on_direct_message, that you and I were expecting.
Here is a working version of the code in 2017
from twitter import *
import os
import oauth
#Create a new Twitter app first: https://apps.twitter.com/app/new
APP_KEY,APP_SECRET = 'H3kQtN5PQgRiA0ocRCCjqjt2P', '51UaJFdEally81B7ZXjGHkDoDKTYy430yd1Cb0St5Hb1BVcDfE'
# OAUTH_TOKEN, OAUTH_TOKEN_SECRET = '149655407-TyUPMYjQ8VyLNY5p7jq0aMy8PjtFtd7zkIpDh3ZA', 'IUVpiDpoVmdO75UaHOTinAv5TOsAQmddttNENh9ofYuWO'
MY_TWITTER_CREDS = os.path.expanduser('my_app_credentials')
if not os.path.exists(MY_TWITTER_CREDS):
oauth_dance("crypto sentiments", APP_KEY, APP_SECRET,
MY_TWITTER_CREDS)
oauth_token, oauth_secret = read_token_file(MY_TWITTER_CREDS)
auth = OAuth(
consumer_key=APP_KEY,
consumer_secret=APP_SECRET,
token=oauth_token,
token_secret=oauth_secret
)
twitter_userstream = TwitterStream(auth=auth, domain='userstream.twitter.com')
for msg in twitter_userstream.user():
if 'direct_message' in msg:
print (msg['direct_message']['text'])