When creating an object of this type:
from tweepy.streaming import StreamListener
from tweepy import OAuthHandler
from tweepy import Stream
class listener(StreamListener):
def __init__(self, consumer_key, consumer_secret, access_token, access_token_secret, a):
StreamListener.__init__(self)
self.auth = OAuthHandler(consumer_key, consumer_secret)
self.auth.set_access_token(access_token, access_token_secret)
self.stream = Stream(self.auth, self)
self.stream.filter(track=tweet_filter.strip().split())
self.a = 2
print access_token
def on_data(self, data):
data_decoded = json.loads(data)
body = data_decoded['text'].encode('utf-8')
print self.a
if __name__ == '__main__':
# parse input arguments
t_listener = listener(consumer_key=params["consumer_key"],
consumer_secret=params["consumer_secret"],
access_token=params["access_token"], access_token_secret=params["access_token_secret"],
a=3)
I don't see access_token printed out, and I also get the error message
'listener' object has no attribute 'a'
self.stream.filter() never returns. It is the point at which the Tweepy API calls out to Twitter, and in a loop receives the twitter stream for your listener to handle. You can't create the stream inside the listener initialiser, as the stream needs the listener to be fully created before it can start.
Simply don't put Stream() handling in the listener. Handle that separately and pass in your StreamListener() instance outside of the __init__ method.
If your listener must have access to the API, just pass it in; the original StreamListener.__init__() method accepts an api argument:
from tweepy.streaming import StreamListener
from tweepy import API
from tweepy import OAuthHandler
from tweepy import Stream
class listener(StreamListener):
def __init__(self, api=None, a=None):
StreamListener.__init__(self, api=api)
self.a = a
def on_data(self, data):
data_decoded = json.loads(data)
body = data_decoded['text'].encode('utf-8')
print self.a
if __name__ == '__main__':
# parse input arguments
auth = OAuthHandler(params["consumer_key"], params["consumer_secret"],)
auth.set_access_token(access_token=params["access_token"], params["access_token_secret"])
api = tweepy.API(auth)
listener = listener(api, 3)
stream = Stream(self.auth, listener)
stream.filter(track=tweet_filter.strip().split())
Related
I tried to get any tweet that contain images. But when I get tweet data in line if media in data.entities:, I get error AttributeError: str object has no attribute entities.
I tried adding to the line
twitterStream = Stream (auth, listener (), include_entities = 1)
but it does not work either
from tweepy import Stream
from tweepy import OAuthHandler
from tweepy.streaming import StreamListener
import pprint
consumer_key = "xxxxxxxxxxxxx"
consumer_secret = "xxxxxxxxxxxxxxxxx"
access_token = "xxxxxxxxxxxxxxxxxx"
access_secret = "xxxxxxxxxxxx"
class listener(StreamListener):
def on_data(self, data):
if 'media' in data.entities:
print(data)
#for image in data.extended_entities['media']:
#print(image['media_url'])
#return(True)
def on_error(self, status):
print ("error")
print (status)
auth = OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_secret)
twitterStream = Stream(auth, listener())
tweets=twitterStream.filter(track=["#picture"])
Tweepy passes the raw text data to tweepy.StreamListener's on_data() method, which is used for handling the raw data from API (so you need to parse JSON string and construst tweepy.Status object).
If you handle normal status objects, you'd better use on_status() method but on_data(). This method takes Tweepy's normal Status object as an argument, so you can use this status object as usual.
So following code
class MyStreamListener(tweepy.StreamListener):
def on_status(self, status):
print('#on_status')
print(type(status))
print(status.text)
def on_error(self, error_code):
print('#on_error')
print(error_code)
if error_code == 420:
return False
stream = tweepy.Stream(api.auth, MyStreamListener())
stream.filter(track=["#picture"])
will print like this:
#on_status
<class 'tweepy.models.Status'>
test1! #picture
#on_status
<class 'tweepy.models.Status'>
This is test picture tweet2! #picture
See also: Streaming With Tweepy — tweepy 3.6.0 documentation
So I have the following python code which receives notification of received direct messages via Tweepy:
#!/usr/bin/env python
from tweepy.streaming import StreamListener
from tweepy import OAuthHandler
from tweepy import Stream
import simplejson as json
consumer_key = "secret"
consumer_secret = "secret"
access_token = "secret"
access_token_secret = "secret"
class StdOutListener(StreamListener):
def __init__(self):
print "init"
def on_connect(self):
print "Connected"
def on_disconnect(self, status):
print ("Disconnected", status)
def on_direct_message(self, status):
print ("on_direct_message", status)
def on_data(self, status):
# print ("on_data", status)
decoded = json.loads(status)
## grab the direct message
directMessage = decoded['direct_message']
message = directMessage.get('text', None)
message.strip()
print "message:*", message, "*"
return True
def on_error(self, status):
print ("on_error", status)
if __name__ == '__main__':
## Connect to Twitter
auth = OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
## Init the StreamListener
print ("Init Stream")
l = StdOutListener()
stream = Stream(auth, l)
stream.userstream()
When it runs and I send the direct message "test message" I get the following printed to the console:
message:* text message *
ie the message was received and parsed but padded with space at either end which message.strip() didn't even correct. If I uncomment the print directMessage line and view the json sent by Twitter there is no space.
I cannot work out if there is a problem with my JSON editing or usage of tweepy or something else.
I've also tried using the json package as well as simplejson.
I have a class MyStreamListener that I'm trying to call from a different file, but I get the type error 'MyStreamListener' not callable. From what I've read when referencing user made classes, it could be because I'm trying to access a reserved keyword in python, but I've already tried changing the name of the class. Is there anything else I'm doing wrong?
functionality.py
from authenticate import CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET
from twitter_stream import MyStreamListener
def oauth_authenticate():
auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
auth.set_access_token(ACCESS_TOKEN, ACCESS_TOKEN_SECRET)
api = tweepy.API(auth)
return api
def streaming():
api = oauth_authenticate()
streamListener = MyStreamListener()
stream = tweepy.Stream(auth=api.auth, listener=streamListener())
if __name__ == '__main__':
print "wanting to stream"
streaming()
print "EXITING"
twitter_stream.py
import tweepy
class MyStreamListener(tweepy.StreamListener):
def on_status(self, status):
print(status.text)
In the line:
stream = tweepy.Stream(auth = api.auth, listener = streamListener())
you are trying to call streamListener since you've got the parens there. Instead, just pass the object itself, i.e.:
stream = tweepy.Stream(auth=api.auth, listener=streamListener)
I'm trying to use the Tweepy python api to create a twitter search stream but I'm facing an error. Here is the code I am trying to execute and the error I'm getting ->
File "code.py", line 28, in <module>
stream = Stream(auth, x, "microsoft")
__init__() takes exactly 3 arguments (4 given)
(Thanks for helping. Sorry, I'm a beginner)
from tweepy.streaming import StreamListener
from tweepy import OAuthHandler
from tweepy import Stream
# Twitter Credentials
access_token_key = "*****"
access_token_secret = "*****"
consumer_key = "*****"
consumer_secret = "*****"
class StdOutListener(StreamListener):
""" A listener handles tweets that are the received from the stream.
This is a basic listener that just prints received tweets to stdout.
"""
def on_data(self, data):
print data
return True
def on_error(self, status):
print status
if __name__ == '__main__':
x = StdOutListener()
auth = OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token_key, access_token_secret)
stream = Stream(auth, x, "microsoft")
response = stream.filter(track=['microsoft'])
print response
Problem lies in stream intitialization line:
stream = Stream(auth, x, "microsoft")
that should be
stream = Stream(auth, x)
tracked words are passed not with constructor but in filter method.
Stream() only takes 2 arguments (plus self for bound methods):
stream = Stream(auth, x)
stream.filter(track=['microsoft'])
See the streaming example given by the Tweepy project.
The 307 redirect should probably be handled as not an error; you can tell Tweepy to continue by returning True from the on_error handler:
def on_error(self, status):
print status
if status == 307:
return True
I'm trying to access the Twitter stream which I had working previously while improperly using Tweepy. Now that I understand how Tweepy is intended to be used I wrote the following Stream.py module. When I run it, I get error code 401 which tells me my auth has been rejected. But I had it working earlier with the same consumer token and secret. Any ideas?
from tweepy.streaming import StreamListener
from tweepy import OAuthHandler
from tweepy import Stream
from tweepy import TweepError
from tweepy import error
#Removed. I have real keys and tokens
consumer_key = "***"
consumer_secret = "***"
access_token="***"
access_token_secret="***"
class CustomListener(StreamListener):
""" A listener handles tweets are the received from the stream.
This is a basic listener that just prints received tweets to stdout."""
def on_status(self, status):
# Do things with the post received. Post is the status object.
print status.text
return True
def on_error(self, status_code):
# If error thrown during streaming.
# Check here for meaning:
# https://dev.twitter.com/docs/error-codes-responses
print "ERROR: ",; print status_code
return True
def on_timeout(self):
# If no post received for too long
return True
def on_limit(self, track):
# If too many posts match our filter criteria and only a subset is
# sent to us
return True
def filter(self, track_list):
while True:
try:
self.stream.filter(track=track_list)
except error.TweepError as e:
raise TweepError(e)
def go(self):
listener = CustomListener()
auth = OAuthHandler(consumer_key, consumer_secret)
self.stream = Stream(auth,listener,timeout=3600)
listener.filter(['LOL'])
if __name__ == '__main__':
go(CustomListener)
For anyone who happens to have the same issue, I should have added this line after auth was initialized:
auth.set_access_token(access_token, access_token_secret)