I am trying to pass a string as a parameter to a function in python(2), but as i try to execute it, i get an error that says:
Error get_all_tweets expected a string or other character buffer object
This is my code:
def get_all_tweets(screen_name):
consumer_key = 'XXXXXXXXXXXXXXXXXXXXXXXX'
consumer_secret = 'XXXXXXXXXXXXXXXXXXXXXXXX'
access_token = 'XXXXXXXXXXXXXXXXXXXXXXXX'
access_secret = 'XXXXXXXXXXXXXXXXXXXXXXXX'
auth = OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_secret)
api = tweepy.API(auth)
alltweets = []
new_tweets = api.user_timeline(screen_name = screen_name, count = 200)
alltweets.extend(new_tweets)
try:
with open('$screen_name.json', 'a') as f:
f.write(alltweets)
return True
except BaseException as e:
print ('Error get_all_tweets %s' % str(e))
return True
get_all_tweets(str("BarackObama"))
I can't understand why i get a complaint about the parameter not being a string, which it clearly is. I am fairly new to python, but every resource i have come across states that this is the way to pass a string as a parameter.
Is there something i have overseen? I don't get any other errors.
I am using Python 2.7.12.
Thanks in advance
The weird error stems from you catching BaseException, something you should never ever do.
The true error is a TypeError: You trying to write a list to a file:
f.write(alltweets)
This won't work, because the write method of a file object only accepts strings or other character buffer objects as arguments.
The way to write a list to a file is by iterating over it:
for tweet in alltweets:
f.write(tweet + "\n")
This will probably not work in your case, because I assume what tweepy returns as a tweet is a dictionary, not a simple string. In that case, use json to encode it:
import json
...
for tweet in alltweets:
f.write(json.dumps(tweet) + "\n")
Related
This question already has answers here:
How to use tweepy for Twitter API v2 in getting user id by username?
(2 answers)
Closed 7 months ago.
I've been having issues getting passed this bug, I was wondering If anyone could help. Or could point me in the right direction? I believe the issue may be with API.get_user. But I just cannot find a workaround it.
This script is supposed to read a csv file of Twitter usernames(list.csv) and pull the unique IDs. Then format those IDs into another csv file.(ids.csv)
here is the error I receive when running get_user_ids.py
these lines end up populating in my newly generated ids.csv file.
get_user() takes 1 positional argument but 2 were given
import tweepy
import time
import csv
import sys
consumer_key = "CONSUMER_KEY"
consumer_secret = "CONSUMER_SECRET"
access_token = "ACCESS_TOKEN"
access_token_secret = "ACCESS_TOKEN_SECRET"
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
api = tweepy.API(auth)
def get_user_ids():
handles = []
with open("list.csv", "r") as csvfile:
reader = csv.reader(csvfile, delimiter=',', quotechar='|')
for row in reader:
for elem in row:
handles.extend(elem.strip().split(','))
for handle in handles:
try:
u = api.get_user(handle[1:-1])
time.sleep(6)
print (u._json['id'])
sys.stderr.write(str(u._json['id']) + "\n")
except Exception as e:
print (e)
if __name__ == '__main__':
get_user_ids()
As shown in the documentation:
API.get_user(*, user_id, screen_name, include_entities)
This means that there are no positional parameters; user_id and screen_name are keyword-only parameters, so the argument must explicitly name the correct keyword:
api.get_user(user_id=handle[1:-1])
or
api.get_user(screen_name=handle[1:-1])
Choose the correct one according to how handle[1:-1] should be interpreted:
user_id – Specifies the ID of the user. Helpful for disambiguating when a valid user ID is also a valid screen name.
screen_name – Specifies the screen name of the user. Helpful for disambiguating when a valid screen name is also a user ID.
I am using the code time.sleep(3600) and it is tweeting more than every 3600 seconds. Why is this happening?
Currently it is tweeting at 9 minutes past, then 32 minutes past.
Edit:
Here is the code. The only other reason this could be happening is that this may be running in multiple instances accidentally. I will check that.
# tweepy will allow us to communicate with Twitter, time will allow us to set how often we tweet
import tweepy, time
#enter the corresponding information from your Twitter application management:
CONSUMER_KEY = 'mykey' #keep the quotes, replace this with your consumer key
CONSUMER_SECRET = 'mykey' #keep the quotes, replace this with your consumer secret key
ACCESS_TOKEN = 'my-my' #keep the quotes, replace this with your access token
ACCESS_SECRET = 'mykey' #keep the quotes, replace this with your access token secret
# configure our access information for reaching Twitter
auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
auth.set_access_token(ACCESS_TOKEN, ACCESS_SECRET)
# access Twitter!
api = tweepy.API(auth)
# open our content file and read each line
filename=open('content.txt')
f=filename.readlines()
filename.close()
# for each line in our contents file, lets tweet that line out except when we hit a error
for line in f:
try:
api.update_status(line)
print("Tweeting!")
except tweepy.TweepError as err:
print(err)
time.sleep(3600) #Tweet every hour
print("All done tweeting!")
This may be caused by your module not being protected from running when imported.
That means every time your module is imported, (could happen on
from package import *
), your code is interpreted and a new loop is created.
You could ensure your code is run only when you want it to run with this :
Make a function from your code, let's name it main().
You can then check if your module is called as a script.
def main():
# tweepy will allow us to communicate with Twitter, time will allow us to set how often we tweet
import tweepy, time
#enter the corresponding information from your Twitter application management:
CONSUMER_KEY = 'mykey' #keep the quotes, replace this with your consumer key
CONSUMER_SECRET = 'mykey' #keep the quotes, replace this with your consumer secret key
ACCESS_TOKEN = 'my-my' #keep the quotes, replace this with your access token
ACCESS_SECRET = 'mykey' #keep the quotes, replace this with your access token secret
# configure our access information for reaching Twitter
auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
auth.set_access_token(ACCESS_TOKEN, ACCESS_SECRET)
# access Twitter!
api = tweepy.API(auth)
# open our content file and read each line
filename=open('content.txt')
f=filename.readlines()
filename.close()
# for each line in our contents file, lets tweet that line out except when we hit a error
for line in f:
try:
api.update_status(line)
print("Tweeting!")
except tweepy.TweepError as err:
print(err)
time.sleep(3600) #Tweet every hour
print("All done tweeting!")
if __name__ == "__main__":
main()
If you have to use your code from another script, you can use
from your_module import main
main()
Or from a command line :
python -m your_module
This is a pretty basic question, but regardless its had me stumped for a bit. I'm trying to access a specific attribute of a tweet (documentation found here), such as "text". I tried accessing it via data["text"], however this gives me the following error TypeError: string indices must be integers.
So I tried parsing the data using json.loads(data) thinking this would allow me to access each attribute of the tweet. However this instead returns solely the text portion of the tweet, meaning when I do print(newData), it prints out the text. Although this is useful, I need to be able to access other attributes of the tweet such as "created_at".
So my question is, how do I parse the tweet or access it which allows me to pluck out individual attributes I need. To reiterate, I'm sure this is pretty simple, however I'm new to handling JSON objects, and other solutions I found simply told me to use loads(), which isn't what I want.
class TwitterStreamer():
"""
Class for streaming and processing live tweets for a given list of hashtags
"""
def stream_tweets(selfself, hashtag_list):
listener = StdOutListener()
auth = OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
auth.set_access_token(ACCESS_TOKEN, ACCESS_TOKEN_SECRET)
stream = Stream(auth, listener)
stream.filter(track=hashtag_list)
class StdOutListener(StreamListener):
def on_data(self, data):
print(data)
newData = json.loads(data)
print(newData["text"])
return True
def on_error(self, status):
print(status)
def main():
hashtag_list = ['Chelsea']
fetched_tweets_filename = "tweets.json"
twitter_streamer = TwitterStreamer()
twitter_streamer.stream_tweets(hashtag_list)
main()
Try using "." operator to access attributes of the tweet. I used it in my code as follow:
tweet = follow_user.status.created_at
In this I got the user in the form of JSON data "status" is an attribute of that JSON object "follow_user"
Try using json.load() to load the JSON as a Python object. The method json.loads() load the JSON as a string, that's why it gives you a TypeError Exception since string objects indices can only be integers.
I'm trying to use the tweepy library in one of my python projects. When I try the following code that creates a tweepy cursor to fetch a user's timeline status messages, the count parameter is always ignored.
def search(self, username, keyword, consumer_key, consumer_secret, access_token, access_token_secret):
#start twitter auth
try:
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
api = tweepy.API(auth)
user = api.get_user(username)
except Exception as e:
print(str(e))
self.error = str(e)
return
self.followercount = user.followers_count
self.screenname = user.screen_name
results = []
for status in tweepy.Cursor(api.user_timeline, id=username, count=2).items():
try:
tweet = status._json
In this instance, the count is set to 2 in the Cursor object, yet it receives all of them. What am I doing wrong?
tweepy.Cursor() does not appear to recognize a count argument. In fact, count is not mentioned anywhere in tweepy/cursor.py, the module where tweepy.Cursor is defined. Instead, it looks like you might want to use:
for status in tweepy.Cursor(api.user_timeline, id=username).items(2):
passing the limit to items() instead of as the count keyword argument. See this section in the tweepy Cursor tutorial.
I am wondering why this code does not return for every json object the desired text?
# import
import json
from twitter import Twitter, OAuth, TwitterHTTPError, TwitterStream
# Authentication
ACCESS_TOKEN = 'hidden'
ACCESS_SECRET = 'hidden'
CONSUMER_KEY = 'hidden'
CONSUMER_SECRET = 'hidden'
oauth = OAuth(ACCESS_TOKEN, ACCESS_SECRET, CONSUMER_KEY, CONSUMER_SECRET)
# TWITTER SEARCH
twitter = Twitter(auth=oauth)
search_tweets = twitter.search.tweets(q='#google')
json_dump = json.dumps(search_tweets)
for line in json_dump:
print(json_dump['text'])
It gives me the following error:
Traceback (most recent call last):
File "twitter_streaming.py", line 46, in
print(json_dump['text'])
TypeError: string indices must be integers
This line:
json_dump = json.dumps(search_tweets)
converted the search_tweets variable into a string containing JSON in it. The issue is then with this code:
for line in json_dump:
print(json_dump['text'])
What this code does is iterates over the characters in json_dump (since json_dump is now a string), and then for each character, tries getting the ['text'] index from this character, which is obviously possible.
It seems like you need to convert search_tweets to a list of dictionaries instead, in order to make it work with your later code. However, without an example output of the search_tweets variable I can't say what exact code you need to do - if you could add the contents of the search_tweets variable that would be helpful.