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.
Related
Using tweepy I am able to return all of my friends using a cursor. Is it possible to specify another user and get all of their friends?
user = api.get_user('myTwitter')
print "Retreiving friends for", user.screen_name
for friend in tweepy.Cursor(api.friends).items():
print "\n", friend.screen_name
Which prints a list of all my friends, however if I change the first line
to another twitter user it still returns my friends. How can I get friends for any given user using tweepy?
#first line is changed to
user = api.get_user('otherUsername') #still returns my friends
Additionally user.screen_name when printed WILL return otherUsername
The question Get All Follower IDs in Twitter by Tweepy does essentially what I am looking for however it returns only a count of ID's. If I remove the len() function I will I can iterate through a list of user IDs, but is it possible to get screen names #twitter,#stackoverflow, #etc.....?
You can use the ids variable from the answer you referenced in the other answer to get the the id of the followers of a given person, and extend it to get the screen names of all of the followers using Tweepy's api.lookup_users method:
import time
import tweepy
auth = tweepy.OAuthHandler(..., ...)
auth.set_access_token(..., ...)
api = tweepy.API(auth)
ids = []
for page in tweepy.Cursor(api.followers_ids, screen_name="McDonalds").pages():
ids.extend(page)
time.sleep(60)
screen_names = [user.screen_name for user in api.lookup_users(user_ids=ids)]
You can use this:
# import the module
import tweepy
# assign the values accordingly
consumer_key = ""
consumer_secret = ""
access_token = ""
access_token_secret = ""
# authorization of consumer key and consumer secret
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
# set access to user's access key and access secret
auth.set_access_token(access_token, access_token_secret)
# calling the api
api = tweepy.API(auth)
# the screen_name of the targeted user
screen_name = "TwitterIndia"
# printing the latest 20 friends of the user
for friend in api.friends(screen_name):
print(friend.screen_name)
for more details see https://www.geeksforgeeks.org/python-api-friends-in-tweepy/
A little help please. This is what I am working with now (I got it from here on stackoverflow) and it works very well, but it seems to only work with the most recent accounts in the list of accounts that don't follow me back. I want to start unfollowing accounts from the oldest to the newest because I keep reaching the limit of the API. I thought to make a list of followers and reverse it then plug that in somewhere but not quite sure how to do that or what the syntax would be. Thanks in advance.
import tweepy
from cred import *
from config import QUERY, UNFOLLOW, FOLLOW, LIKE, RETWEET
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
api = tweepy.API(auth, wait_on_rate_limit=True)
def main():
try:
if UNFOLLOW:
my_screen_name = api.get_user(screen_name='YOUR_SCREEN_NAME')
for follower in my_screen_name.friends():
Status = api.get_friendship(source_id = my_screen_name.id , source_screen_name = my_screen_name.screen_name, target_id = follower.id, target_screen_name = follower.screen_name)
if Status [0].followed_by:
print('{} he is following You'.format(follower.screen_name))
else:
print('{} he is not following You'.format(follower.screen_name))
api.destroy_friendship(screen_name = follower.screen_name)
except tweepy.errors.TweepyException as e:
print(e)
while True:
main()
here is the config.py file
#config.py
UNFOLLOW = True
I recently assembled some pieces of code together to reach this, so I'll just copy paste what I already have here instead of updating your code, but I can point out the main points (and give some tips).
The full code:
import tweepy
from cred import *
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
api = tweepy.API(auth, wait_on_rate_limit=True)
def unfollower():
followers = api.get_follower_ids(screen_name=api.verify_credentials().screen_name)
friends = api.get_friend_ids(screen_name=api.verify_credentials().screen_name)
print("You follow:", len(friends))
for friend in friends[::-1]:
if friend not in followers:
api.destroy_friendship(user_id = friend)
else:
pass
friends = api.friends_ids(screen_name=api.me().screen_name)
print("Now you're following:", len(friends))
unfollower()
Now what happened here and what is different from your code
This two variables:
followers = api.followers_ids(screen_name=api.verify_credentials().screen_name)
friends = api.friends_ids(screen_name=api.verify_credentials().screen_name)
create a list with the ids from both the followers (follow you) and the friends (you are following), now all we need to do is compare both.
There is a discussion about the Twitter Rate limit and how using cursors have a smaller rate than not using, but I'm not qualified to explain the whys, so let's just assume that if we do not want small rate limits, the best way is not to use requests that have a intrinsic small rate limit like the api.get_friendship and them getting the screen_name, instead I'm using the get_friend_ids method.
the next part involves what you called "make a list of followers and reverse", well the list is already there in the variable "followers", so all we need to do now is reverse read it with the following command:
for friend in friends[::-1]:
this says: "read each element of the list, starting from index -1" roughtly "read the list backwards".
Well, I think the major points are these, I created a function but you really don't even need to, is just easier to update this to a class if you need to, and this way you don't need to use the while True: main(), just call the function unfollow() and it will automatically end the script when the unfollows are over.
Now some minor points that might improve your code:
Instead of using
screen_name='YOUR_SCREEN_NAME'
That you need a config file or to hardcode the screen_name, you can use
screen_name=api.verify_credentials().screen_name
This way it will automatically knows that you want the authenticating user information (note that I didn't used this part on my code, for the get_friend_ids method does not need the screen_name)
Now this part
from cred import *
from config import QUERY, UNFOLLOW, FOLLOW, LIKE, RETWEET
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
api = tweepy.API(auth, wait_on_rate_limit=True)
First I've eliminated the need for the config file
and you can eliminate all the extra info that comes imported from the cred file, so you don't need to import all in from cred import * updating cred.py with:
import tweepy
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
api = tweepy.API(auth, wait_on_rate_limit=True)
and now you can only impor the api function with from cred import api, this way the code can become cleaner:
import tweepy
from cred import api
def unfollower():
followers = api.get_follower_ids(screen_name=api.verify_credentials().screen_name)
friends = api.get_friend_ids(screen_name=api.verify_credentials().screen_name)
print("You follow:", len(friends))
for friend in friends[::-1]:
if friend not in followers:
api.destroy_friendship(user_id = friend)
else:
pass
friends = api.get_friend_ids(screen_name=api.verify_credentials().screen_name)
print("Now you're following:", len(friends))
unfollower()
Lastly, if anyone is having problems with the api.get_friend_ids or get_follower_ids remember that the tweepy update for versions 4.x.x changed the name of some methods, the ones I remember are:
followers_ids is now get_follower_ids
friends_ids is now get_friend_ids
me() is now verify_credentials()
Well, I guest that's it, you can check the rest on the docs.
Happy pythoning!
I'm very much new to python. I need a code which will fetch the tweets and the places from where it is tagged,or geo-tagged tweets.
I Have code which will export the tweets the csv file based o the hash tag given, I want another column added, with specifies from where it is tweeted.
Please help me on this.
The code is as follows,
import tweepy
import csv
import pandas as pd
####input your credentials here
consumer_key = ''
consumer_secret = ''
access_token = '-'
access_token_secret = ''
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
api = tweepy.API(auth,wait_on_rate_limit=True)
csvFile = open('mydoc.csv', 'a')
#Use csv Writer
csvWriter = csv.writer(csvFile)
for tweet in tweepy.Cursor(api.search,q="#iPhoneX",count=100,
lang="en",
since="2017-01-01").items():
print (tweet.created_at, tweet.text)
csvWriter.writerow([tweet.created_at, tweet.text.encode('utf-8')])
I'm in very much in need of it.Please help !!!
I think you can do like this:
for tweet in tweepy.Cursor(api.search, q="#iPhoneX", count=100, lang="en",
since="2017-01-01").items():
if tweet.coordinates or tweet.geo:
print(tweet.id_str, tweet.coordinates, tweet.geo)
You can see the structure of a tweet object (also called status) here. The different fields correspond to:
coordinates: "Represents the geographic location of this Tweet as reported by the user or client application. The inner coordinates array is formatted as geoJSON (longitude first, then latitude)"
place: "When present, indicates that the tweet is associated (but not necessarily originating from) a Place". This happens when the user tagged a place for the tweet.
geo: "Deprecated. Use the coordinates field instead. This deprecated attribute has its coordinates formatted as [lat, long], while all other Tweet geo is formatted as [long, lat]."
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")
i'm trying to tweepy to reply to certain tweets, and my reply includes an image.
the twt variable holds the tweet i'm trying to reply to.
here's what i'm doing at the moment:
# -*- coding: utf-8 -*-
import tweepy, time, random
CONSUMER_KEY = 'XXXX'
CONSUMER_SECRET = 'XXXX'
ACCESS_KEY = 'XXXX'
ACCESS_SECRET = 'XXXX'
auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
auth.set_access_token(ACCESS_KEY, ACCESS_SECRET)
api = tweepy.API(auth)
query = ['aaa', 'bbb', 'ccc']
t0 = time.time()
count = 0
last_count = 0
f = open('last_replied.txt')
last_replied = int(f.readline().strip())
f.close()
print('starting time:', time.strftime('%X'))
while True:
if count > last_count:
print(time.strftime('%X'), ':', count, 'replies')
last_count = count
for i in range(3):
twts = api.search(query[i], since_id=last_replied)
if len(twts)>0:
for twt in twts:
sid = twt.id
sn = twt.user.screen_name
stat = "lalala" + "#" + sn
api.update_with_media('oscar1.gif',status=stat,in_reply_to_status_id=sid)
count += 1
last_replied = twt.id
f = open('last_replied.txt','w')
f.write(str(last_replied))
f.close()
pause = random.randint(50,90)
time.sleep(pause)
my tweet gets posted, but not as a reply to the original tweet (twt). instead, it just gets posted as a new, independent, tweet.
however, when instead of update_with_media as above, i use update_status, such as:
api.update_status(status=stat,in_reply_to_status_id=sid)
my new tweet does get posted as a reply to the original tweet (twt).
what am i missing?
thanks
the solution i ended up with was switching to the twython module, that has the functionality well documented and working perfectly.
thank you very much for your help.
The update_with_media endpoint is being deprecated by Twitter (https://dev.twitter.com/rest/reference/post/statuses/update_with_media) you shouldn't use it. Instead upload the media first with the media_upload method and add the media_ids you get back to the update_status method.
I glanced at the code for update_with_media and don't see any obvious bugs, but the new method of handling tweets with media was added to the Tweepy API in January - note the last two bullets here:
https://github.com/tweepy/tweepy/releases/tag/v3.2.0
If you download Tweepy 3.2.0 you should be able to switch over to the new regimen, which will hopefully fix your reply_to problem. (I can't say for sure if the new stuff works, I'm using an older version of Tweepy myself.)