tweepy It won't follow some of the tweets - python-3.x

seems like for some of the tweets with the keyword 'follow'
it will follow and for some of them it wont...
other than that it works fine(I didn't notice something else)
can someone pinpoint where is the problem?
class Listener():
def search(self, twts):
global numoftwts
for i in twts:
names = ['follow', 'following']
txt = i.text.lower()
if not any(k in txt for k in keywords) or any(k in txt for k in bannedwords):
continue
if not self.is_user_bot_hunter(str(i.author.screen_name)):
if not i.retweeted:
try:
print("Trying to retweet status_id:{}".format(i.id))
res = api.retweet(i.id)
if res.retweeted:
api.create_favorite(i.id)
print('retweeted', numoftwts, 'times', '-',
str(datetime.datetime.fromtimestamp(time.time()).strftime('%d-%m-%Y %H:%M:%S')))
print(i.text)
print('\n')
else:
print("retweet failed")
if any(c in txt for c in names):
# print("Trying to follow something")
# if hasattr(i, 'retweeted_status'):
# print("trying to fetch user_id")
user_id = i.retweeted_status.user.id_str
res = api.create_friendship(user_id)
res = api.get_user(user_id)
if res.following:
print("Successfully followed :{}".format(user_id))
print('\n')
except Exception as e:
print("Exception:".format(str(e)))
continue
sleep(600)
def run(self):
for eachkey in keywords:
tweets = api.search(q=eachkey, result_type='mixed', lang='en')
self.search(tweets)
if __name__ == '__main__':
while True:
r = Listener()
r.run()
where did I go wrong?
AttributeError: 'Status' object has no attribute 'retweeted_status'
> c:\users\x\desktop\twitterbot\twtbotcopy.py(64)search()
-> user_id = i.retweeted_status.user.id_str
(Pdb) n
> c:\users\x\desktop\twitterbot\twtbotcopy.py(70)search()
-> except Exception as e:
(Pdb) n

If your getting any error where you are unable to get tweets from a particular user then use:
try:
specific_tweets = tweepy.Cursor(api.search, tweet_mode='extended', q= <some query>, lang='en').items(500)
except tweepy.error.TweepError:
pass
And if you want to access the retweeted attribute of a tweet then do this:
if hasattr(tweet, 'retweeted_status'):
extracted_author = tweet.retweeted_status.user.screen_name
else: extracted_author = tweet.user.screen_name
basically check whether hasattr(tweet, 'retweeted_status') of a tweet is true or not. It checks whether the tweet has the attribute named "retweeted_status"

AttributeError: 'Status' object has no attribute 'retweeted_status'
-> user_id = i.retweeted_status.user.id_str
It means that you want to get the user ID of a retweet, for a tweet that is not a retweet.
I you want to know if a tweet is a RT, the test is :
if hasattr(tweet, 'retweeted_status'):
# this tweet is a RT

Related

Failed to Retrieve HTTP Error 401: Unauthorized

I'm running a python script to connect to the twitter api and count my friends. When I run it I get the 401 error in the title. Any help would be appreciated.
`
import urllib.request, urllib.parse, urllib.error
import twurl
import json
import sqlite3
import ssl
TWITTER_URL = 'https://api.twitter.com/1.1/friends/list.json'
conn = sqlite3.connect('friends.sqlite')
cur = conn.cursor()
cur.execute('''CREATE TABLE IF NOT EXISTS People
(id INTEGER PRIMARY KEY, name TEXT UNIQUE, retrieved INTEGER)''')
cur.execute('''CREATE TABLE IF NOT EXISTS Follows
(from_id INTEGER, to_id INTEGER, UNIQUE(from_id, to_id))''')
Ignore SSL certificate errors
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
while True:
acct = input('Enter a Twitter account, or quit: ')
if (acct == 'quit'): break
if (len(acct) < 1):
cur.execute('SELECT id, name FROM People WHERE retrieved=0 LIMIT 1')
try:
(id, acct) = cur.fetchone()
except:
print('No unretrieved Twitter accounts found')
continue
else:
cur.execute('SELECT id FROM People WHERE name = ? LIMIT 1',
(acct, ))
try:
id = cur.fetchone()[0]
except:
cur.execute('''INSERT OR IGNORE INTO People
(name, retrieved) VALUES (?, 0)''', (acct, ))
conn.commit()
if cur.rowcount != 1:
print('Error inserting account:', acct)
continue
id = cur.lastrowid
url = twurl.augment(TWITTER_URL, {'screen_name': acct, 'count': '100'})
print('Retrieving account', acct)
try:
connection = urllib.request.urlopen(url, context=ctx)
except Exception as err:
print('Failed to Retrieve', err)
break
data = connection.read().decode()
headers = dict(connection.getheaders())
print('Remaining', headers['x-rate-limit-remaining'])
try:
js = json.loads(data)
except:
print('Unable to parse json')
print(data)
break
Debugging
print(json.dumps(js, indent=4))
if 'users' not in js:
print('Incorrect JSON received')
print(json.dumps(js, indent=4))
continue
cur.execute('UPDATE People SET retrieved=1 WHERE name = ?', (acct, ))
countnew = 0
countold = 0
for u in js['users']:
friend = u['screen_name']
print(friend)
cur.execute('SELECT id FROM People WHERE name = ? LIMIT 1',
(friend, ))
try:
friend_id = cur.fetchone()[0]
countold = countold + 1
except:
cur.execute('''INSERT OR IGNORE INTO People (name, retrieved)
VALUES (?, 0)''', (friend, ))
conn.commit()
if cur.rowcount != 1:
print('Error inserting account:', friend)
continue
friend_id = cur.lastrowid
countnew = countnew + 1
cur.execute('''INSERT OR IGNORE INTO Follows (from_id, to_id)
VALUES (?, ?)''', (id, friend_id))
print('New accounts=', countnew, ' revisited=', countold)
print('Remaining', headers['x-rate-limit-remaining'])
conn.commit()
cur.close()`
Also, I am running this in Visual Studio Code in case that matters.
I tried to cd into the proper folder as at first Visual Studio Code was running the code from a different folder and I thought it didn't have the files it needed to import, etc. I was expecting the file to be found so I could run the program correctly, I assume right now I am having troubles with the OAuth.

Problem retrieving individual objects in pickled dictionary (Python 3)

My program stores "food" objects that are pickled into a dictionary and stored in a csv file, which acts as a database. I want to retrieve individual food objects on command from the dictionary, but when I attempt to I seem to only retrieve the last object in the dictionary.
import pickle
class Food(object):
fooddict = dict({})
def __init__(self, name, weight, calories, time):
self.name = name
self.weight = weight
self.calories = calories
self.time = time
def __str__(self):
return '{self.name}s'.format(self=self) + \
' weigh {self.weight}'.format(self=self) + \
' ounces, contain {self.calories}'.format(self=self) + \
' calories, and stay fresh for {self.time}'.format(self=self) + \
' days.'
#classmethod
def createFoodInput(cls):
name = str(input("Enter the name: "))
weight = float(input("Enter the weight: "))
calories = float(input("Enter the calories: "))
time = float(input("Enter how many days it can store for: "))
return cls(name, weight, calories, time)
def storeFoodDict(f):
fooddict = Food.retreiveFoodDict()
if fooddict == "Empty File":
fooddict = dict({f.name: f})
with open("food.csv", 'wb') as filewriter:
try:
pickle.dump(fooddict, filewriter)
except:
print("Error storing pickled dictionary")
else:
food_found = False
for key in list(fooddict):
if key.__eq__(f.name):
print("Food already stored!")
food_found = True
if not food_found:
fooddict.update({f.name: f})
with open("food.csv", 'wb') as filewriter:
try:
pickle.dump(fooddict, filewriter)
except:
print("Error storing pickled dictionary")
#classmethod
def retreiveFoodDict(cls):
with open("food.csv", 'rb') as filereader:
try:
fooddict = pickle.load(filereader)
return fooddict
except EOFError:
return("Empty File")
def findFood(title):
fooddict = Food.retreiveFoodDict()
for key in list(fooddict):
if key.__eq__(title):
continue
return fooddict[key]
s = "apple"
n = findFood(s) #does not work, it returns banana instead of apple
#which is really just grabbing whatever is the
#last object in the dictionary
m = findFood("banana") #seems to work, but only because banana is the
#last object in the dictionary
print(n) #should print an apple "food object" but instead prints a banana
print(str(m.calories)) #works, but if I said n.calories it would still print
#m.calories instead
p = Food.retreiveFoodDict() #seems to work and retrieve the dictionary
print(str(p)) #also seems to work of course
Console Output:
bananas weigh 5.0 ounces, contain 120.0 calories, and stay fresh for 3.0 days.
120.0
{'apple': <main.Food object at 0x00D2C2E0>, 'banana': <main.Food object at 0x00D36D00>}
The dictionary contains 2 food objects (apple and banana), but the print(n) statement shows a banana, not an apple. Can anyone point out why this is or what I am misunderstanding? Thank you so much!
I found the answer to my own problem. I was misusing the continue in my findFood function.
This code solved my issues.
def getFood(food_name):
fooddict = Food.retreiveFoodDict()
for key in list(fooddict):
if key.__eq__(food_name):
return fooddict[key]
What this function does is simply retrieve a dictionary of objects in a csv file and iterates through the keys until the passed key name is located. If found, the proper key name will be returned as a food object. My original mistake was using the "continue" keyword to stop the for-loop, which was returning the object directly after the one we wanted.

Why do I keep getting the AttributeError: 'str' object has no attribute 'Student' when running my program

I am trying to run a program that implements Object Oriented Programming to help a student register for a course. I keep running into an Attribute Error and can't seem to figure out where my code went wrong.
I initially thought it had something to do with the fact that I had not implemented the self parameter in all the method def statements. But after I fixed this, I still encountered the same error message.
ONE = 1
TWO = 2
THREE = 3
FOUR = 4
FIVE = 5
TRUE = True
FALSE = False
COURSES_INPUT = 'courses-sample.txt'
STUDENTS_INPUT= 'students-sample.txt'
import student
import course
def main():
process_students()
process_courses()
option = get_option()
while option != 5:
if option == 1:
course_num = input('please input course number of course you wish to add: ')
add_course = new_student.add_course(course_num)
while add_course == FALSE:
print('The course requested for add does not exist. Please Try Again.')
course_num = input('Please input course number of course you wish to add: ')
if new_course.space_available() == TRUE:
new_course.enroll_student()
else:
print('Class requested does not have any seats available.')
if option == 2:
course_num = input('please input course number of course you wish to drop: ')
drop_course = new_student.drop_course(course_num)
while drop_course == FALSE:
print('The enrolled course requested for drop does not exist. Please Try Again.')
course_num = input('Please input course number of course you wish to drop: ')
new_course.drop_student()
if option == 3:
print_student_info(student_dict)
if option == 4:
print_course_schedule(course_dict)
option = get_option()
write_updated('students-updated.txt',student_dict)
write_updated('courses-updated.txt',course_dict)
def print_menu():
print("1. Add course")
print("2. Drop course")
print("3. Print student's schedule")
print("4. Print course schedule")
print("5. Done")
print("")
def get_option():
print_menu()
choice = input("What would you like to do? ")
while choice not in range(1,6):
print_menu()
choice = input("Choice is invalid. What would you like to do? ")
return choice
def process_students():
student_dict = {}
student_info = open(STUDENTS_INPUT,"r")
for student in student_info:
info_list = student.split(":")
new_id = info_list[0]
first_name = info_list[1]
last_name = info_list[2]
course_list = info_list[3:]
new_student = student.Student(new_id, first_name, last_name, course_list)
print(new_student.line_for_file())
student_dict[new_eid] = new_student
student_info.close()
def process_courses():
course_dict = {}
course_info = open(COURSES_INPUT,"r")
for course in course_info:
info_list = course.split(";")
unique_num = info_list[0]
class_name = info_list[1]
prof = info_list[2]
seats = info_list[3]
capacity = info_list[4]
new_course = course.Course(unique_num, class_name, prof, seats, capacity)
course_dict[unique_num] = new_course
course_info.close()
def print_course_schedule(course_dict):
for value in course_dict:
print(value)
def print_student_info(student_dict):
for value in student_dict:
print(value)
def get_id():
eid = input("What is the UT EID? ")
while eid not in student_dict:
eid = input("Invalid UT EID. Please re-enter: ")
return eid
def get_unique():
unique = input("What is the course unique number? ")
while unique not in course_dict:
unique = input("Invalid unique number. Please re-enter: ")
return unique
def write_updated(filename,dictionary):
output_file = open(filename,'w')
for key in dictionary:
output_file.write(dictionary[key])
output_file.close()
main()
Error Message:
Traceback (most recent call last):
File "C:\Users\njung\Downloads\MIS 304 Final Project\untitled folder\Nguyen_Calvin_Jung_Nicholas-FP.py", line 132, in <module>
main()
File "C:\Users\njung\Downloads\MIS 304 Final Project\untitled folder\Nguyen_Calvin_Jung_Nicholas-FP.py", line 24, in main
process_students()
File "C:\Users\njung\Downloads\MIS 304 Final Project\untitled folder\Nguyen_Calvin_Jung_Nicholas-FP.py", line 83, in process_students
new_student = student.Student(new_id, first_name, last_name, course_list)
AttributeError: 'str' object has no attribute 'Student'
>>>
I also have the classes used stored in separate files (was required for the program) and have imported the modules containing these classes into main as you can see at the top.
Your error is AttributeError: 'str' object has no attribute 'Student'
Looking at the trace, it seems that it originates from this code:
student_info = open(STUDENTS_INPUT,"r")
for student in student_info:
info_list = student.split(":")
new_id = info_list[0]
first_name = info_list[1]
last_name = info_list[2]
course_list = info_list[3:]
new_student = student.Student(new_id, first_name, last_name, course_list)
Here you've opened a file. student_info is the file, and you iterate over the lines in the file. Each line student is a string.
You later call student.Student(new_id, first_name, last_name, course_list), but since student is just a string, it naturally does not contain a Student method.

urllib error: Too many requests

The below python program asks the user for two reddit usernames and compares their score.
import json
from urllib import request
def obtainKarma(users_data):
users_info = []
for user_data in users_data:
data = json.load(user_data)
posts = data["data"]["children"]
num_posts = len(posts)
scores = []
comments = []
for post_id in range(num_posts):
score = posts[post_id]["data"]["score"]
comment = posts[post_id]["num_comments"]
scores.append(score)
comments.append(comment)
users_info.append((scores,comments))
user_id = 0
for user_info in users_info:
user_id+=1
print("User"+str(user_id))
for user_attr in user_info:
print(user_attr)
def getUserInfo():
count = 2
users_data = []
while count:
count = count + 1
username = input("Please enter username:\n")
url = "https://reddit.com/user/"+username+".json"
try:
user_data = request.urlopen(url)
except:
print("No such user.\nRetry Please.\n")
count = count + 1
raise
users_data.append(user_data)
obtainKarma(users_data)
if __name__ == '__main__':
getUserInfo()
However, when I run the program and enter a username, I get an error:
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 429: Too Many Requests
I tried looking for similar issues but none of them satisfied to solve this specific issue. Looking at the error, it would make sense to say that the URL includes an amount of data that exceeds a specific limit? But that still sounds absurd because it is not that much of a data.
Thanks.
The problem seems to be resolved when you supply a User-Agent with your request.
import json
from urllib import request
def obtainKarma(users_data):
users_info = []
for user_data in users_data:
data = json.loads(user_data) # I've changed 'json.load' to 'json.loads' because you want to parse a string, not a file
posts = data["data"]["children"]
num_posts = len(posts)
scores = []
comments = []
for post_id in range(num_posts):
score = posts[post_id]["data"]["score"]
comment = posts[post_id]["data"]["num_comments"] # I think you forgot '["data"]' here, so I added it
scores.append(score)
comments.append(comment)
users_info.append((scores,comments))
user_id = 0
for user_info in users_info:
user_id+=1
print("User"+str(user_id))
for user_attr in user_info:
print(user_attr)
def getUserInfo():
count = 2
users_data = []
while count:
count = count + 1
username = input("Please enter username:\n")
url = "https://reddit.com/user/"+username+".json"
user_data = None
try:
req = request.Request(url)
req.add_header('User-Agent', 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)')
resp = request.urlopen(req)
user_data = resp.read().decode("utf-8")
except Exception as e:
print(e)
print("No such user.\nRetry Please.\n")
count = count + 1
raise # why raise? --> Program will end if user is not found
if user_data:
print(user_data)
users_data.append(user_data)
obtainKarma(users_data)
if __name__ == '__main__':
getUserInfo()
There were still other issues with your code:
You should not write json.load(user_data), because you are parsing a string. So I changed it to use json.loads(user_data).
The Python documentation for json.loads states:
Deserialize s (a str instance containing a JSON document) to a Python object using this conversion table.
And in the code comment = posts[post_id]["num_comments"], I think you forgot to index on 'data', so I changed it to comment = posts[post_id]["data"]["num_comments"]
And why are you raising the exception in the except-block? This will end the program, however it seems that you expect it not to, from looking at the following code:
print("No such user.\nRetry Please.\n")

When I use string,find[::] in another def, the string.find() says it's attribution doesn't work

When i use find() like string.find[::] in another def function, it says that says attribution error. Why does it not work?
def parts(phrase):
space=phrase.find(' ')
first_word=phrase[0:space]
return first_word
def rest_of_phrase(phrase):
space=phrase.find(' ')
rest_of_phrase=phrase[space+1:]
return rest_of_phrase
def jesus_this_part_is_hard(first_word,rest_of_phrase):
total_num=len(rest_of_phrase)
count=0
savepoint=[]
while total_num<count:
for i in total_num:
if i==' ':
savepoint+=[i]
count+=1
print(first_word," ")
x=savepoint[::-1]
for i in x:
if i==x[0]:
print(rest_of_phrase[i:]," ")
p=i
elif i!=x[0]:
print(rest_of_phrase[i:p],"")
p=i
def main():
phrase = input("Enter the phrase")
parts(phrase)
parts(rest_of_phrase)
jesus_this_part_is_hard(first_word,rest_of_phrase)
The result that I got was line 2, in parts
space=phrase.find(' ')
AttributeError: 'function' object has no attribute 'find'
parts(rest_of_phrase) here rest_of_phrase is function hence you are seeing this error
replace your main function with below and it will fix syntax errors (Not sure about the logical errors)
def main()
phrase = input("Enter the phrase")
first_word = parts(phrase)
rest_of_phrase = rest_of_phrase(phrase)
jesus_this_part_is_hard(first_word,rest_of_phrase)

Resources