I'm trying to get the latest 100 posts from my giphy user.
It works for accounts like "giphy" and "spongebob"
But not for "jack0_o"
import requests
def get_user_gifs(username):
api_key = "API_KEY"
limit = 25 # The number of GIFs to retrieve per request (max 25)
offset = 0
# Set a flag to indicate when all GIFs have been retrieved
done = False
# Keep making requests until all GIFs have been retrieved
while not done:
# Make the request to the Giphy API
endpoint = f"https://api.giphy.com/v1/gifs/search?api_key={api_key}&q={username}&limit={limit}&offset={offset}&sort=recent"
response = requests.get(endpoint)
data = response.json()
# Extract the GIF URLs from the data and print them one per line
for gif in data["data"]:
print(gif["url"])
# Update the starting index for the next batch of GIFs
offset += limit
# Check if there are more GIFs to retrieve
if len(data["data"]) < limit or offset >= 100:
done = True
get_user_gifs("spongebob") #WORKS
get_user_gifs("jack0_o") #does not work
Already tried adding ratings with "pg", "r", "g"
Related
I have pulled data from a private slack channel, using conversation history, and it pulls the userid instead of username, how can I change the code to pull the user name so I can identify who each user is? Code below
CHANNEL = ""
MESSAGES_PER_PAGE = 200
MAX_MESSAGES = 1000
SLACK_TOKEN = ""
client = slack_sdk.WebClient(token=SLACK_TOKEN)
# get first page
page = 1
print("Retrieving page {}".format(page))
response = client.conversations_history(
channel=CHANNEL,
limit=MESSAGES_PER_PAGE,
)
assert response["ok"]
messages_all = response['messages']
# get additional pages if below max message and if they are any
while len(messages_all) + MESSAGES_PER_PAGE <= MAX_MESSAGES and response['has_more']:
page += 1
print("Retrieving page {}".format(page))
sleep(1) # need to wait 1 sec before next call due to rate limits
response = client.conversations_history(
channel=CHANNEL,
limit=MESSAGES_PER_PAGE,
cursor=response['response_metadata']['next_cursor']
)
assert response["ok"]
messages = response['messages']
messages_all = messages_all + messages
It isn't possible to change what is returned from the conversations.history method. If you'd like to convert user IDs to usernames, you'll need to either:
Call the users.info method and retrieve the username from the response.
or
Call the users.list method and iterate through the list and create a local copy (or store in a database) and then have your code look it up.
I'm trying to get all the tracks from 2 playlists into a CSV file. However, in both playlists, even though I increase the offset parameter by 100 in each query, the first 100 songs of both playlists are returned. So the page is never changed. What could be the problem?
import spotipy, json, csv
from spotipy.oauth2 import SpotifyClientCredentials
client_credentials_manager = SpotifyClientCredentials(client_id=client_id, client_secret=client_secret)
sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
data_file = open('data.csv', 'w')
writer = csv.writer(data_file)
writer.writerow(['track_num', 'track_id', 'track_name', 'first_artist'] + ['liked'])
playlist_ids = [
'xxxxxxxxxxxxxxxxxxxxxxx', # playlist 1
'yyyyyyyyyyyyyyyyyyyyyyy' # playlist 2
]
for playlist_id in playlist_ids:
offset_n = 0
total = 100
while offset_n < total:
tracks_response = sp.playlist_tracks(playlist_id, offset=offset_n)
tracks_json = json.dumps(tracks_response)
tracks_data = json.loads(tracks_json)
if offset_n == 0:
total = tracks_data['tracks']['total']
for track in tracks_data['tracks']['items']:
track_id = track['track']['id']
track_name = track['track']['name']
first_artist = track['track']['artists'][0]['name']
if playlist_id == playlist_ids[0]:
writer.writerow([row_num, track_id, track_name, first_artist] + [1])
else:
writer.writerow([row_num, track_id, track_name, first_artist] + [0])
offset_n += 100
data_file.close()
The playlist_tracks method returns a paginated result with details of the tracks of a playlist.
So you need to iterate over all pages to get the full data.
You can use this example as a reference:
def get_all_tracks_from_playlist(playlist_id)
tracks_response = sp.playlist_tracks(playlist_id)
tracks = tracks_response["items"]
while tracks_response["next"]:
tracks_response = sp.next(tracks_response)
tracks.extend(tracks_response["items"])
return tracks
Regarding the ReadTimeout exception you have mentioned in the comments:
Spotify client accepts requests_timeout and retries as arguments, according to the documentation the default values are requests_timeout=5, and retries=3
You can extend them as you wish to decrease the chance you will get the ReadTimeout exception.
As a start you can double the request timeout to 10 seconds, and change the retries to 5:
sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager, requests_timeout=10, retries=5)
How do you get Flickr random Images using the API and Python?
I used the following Flickr API:
flickr.photos.search(text,page,per_page,extras)
# where:
# text = "flower" (also with other words the results are very disappointing about the randomness)
# per_page = 1 (I have set 1 Image per page)
# page = In the vast majority of cases, the number of pages found per word exceeds 100000. Therefore I set a random number between 1 and 100000
# extras = "url_sq,url_t,url_s,url_q,url_m,url_n,url_z,url_c,url_l,url_o"
When I launch my application, which displays an Image every 20 seconds, the results are very very disappointing, in the sense that, about every 20 Images displayed, 16 are always the same Image.
Below the entire code:
def update_flickrImage(self):
FLICKR_PUBLIC = 'XXXXXXXXXXXXXXXXXX'
FLICKR_SECRET = 'XXXXXXXXXXX'
flickr = FlickrAPI(FLICKR_PUBLIC,FLICKR_SECRET,format='parsed-json')
random.seed()
rand_page = random.randrange(1,100000,1)
extras = 'url_sq,url_t,url_s,url_q,url_m,url_n,url_z,url_c,url_l,url_o'
cats = flickr.photos.search(text="flower", page=rand_page, per_page=1, extras=extras)
photos = cats['photos']
pprint(photos)
print("Page: ",rand_page)
for image in photos['photo']:
self.title = image['title']
try:
url = image['url_o']
width = image['width_o']
height = image['height_o']
except:
try:
url = image['url_l']
width = image['width_l']
height = image['height_l']
except:
try:
url = image['url_c']
width = image['width_c']
height = image['height_c']
except:
pass
try:
r = requests.get(url)
self.pic = r.content
except:
pass
I tried your code as close I could. When I ran the test on 100 calls, I only got back 3 different links.
When I reduced the number to 4000 in the randrange function, I got 98 unique URLs out of 100. The whole code is below (with my public and secret commented out):
import flickrapi as fa
import random
# import pprint as pp
import time as ti
def update_flickrImage(self):
FLICKR_PUBLIC = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
FLICKR_SECRET = 'XXXXXXXXXXXXXXXX'
flickr = fa.FlickrAPI(FLICKR_PUBLIC,FLICKR_SECRET,format='parsed-json')
random.seed()
rand_page = random.randrange(1,4000,1)
extras = 'url_sq,url_t,url_s,url_q,url_m,url_n,url_z,url_c,url_l,url_o'
cats = flickr.photos.search(text="flower",
page=rand_page,
per_page=1,
extras=extras)
photos = cats['photos']
# pp.pprint(photos)
print("Page: ",rand_page)
for image in photos['photo']:
title = image['title']
try:
url = image['url_o']
width = image['width_o']
height = image['height_o']
except:
try:
url = image['url_l']
width = image['width_l']
height = image['height_l']
except:
try:
url = image['url_c']
width = image['width_c']
height = image['height_c']
except:
pass
self['title'] = title
self['url'] = url
self['width'] = width
self['height'] = height
return url
imgobj = {'title':'A','url':'https','width':'0','height':'0'}
for i in range(100):
imgurl = update_flickrImage(imgobj)
print( imgurl)
ti.sleep(2)
Flickr search API has a limit of 4000 records returned per search query.
In my Flickr account I have over 13,000 photos. I can download 100 at a time for up to 1400 pages when I need to make a local searchable database in MySQL. I do most of my Flickr work with PHP.
Yeah, you have to play with it. A search for "flower" returns 295,805 pages. That's too much.
Also in my version of your code, I had to comment out the pretty print. Title would blow it up with certain UTF characters. I just wanted to see unique URLs.
I'm having fun with the FB Graph API collecting "reactions" until I hit the FB limit of 100. (Some of the posts I need to query have well over 1000 reactions)
I do see dictionary key "next" in the json response which is a link to the next group and that group has a next key and so on. Below is a simplified version of what I have so far...
post_id_list = ['387990201279405_1155752427836508'] #short list for this example
def make_post_reaction_url_list(postid_list, APP_ID, APP_SECRET):
''' constructs a list of FB urls to gather reactions to posts limit set to 3'''
post_id_list_queries = []
for post_id in postid_list:
post_id_list_queries.append("https://graph.facebook.com/v2.8/"+post_id+"?fields=reactions.limit(3)&access_token="+ APP_ID + "|" + APP_SECRET)
return post_id_list_queries
post_id_reaction_query_list = make_post_reaction_url_list(post_id_list, APP_ID, APP_SECRET)
def return_json_from_fb_query(post_id_rection_query_list):
list_o_json = []
for target in post_id_reaction_query_list:
t = requests.get(target)
t_json = t.json()
list_o_json.append(t_json)
return list_o_json
list_o_json = return_json_from_fb_query(post_id_reaction_query_list)
list_o_json[0]['reactions']['data'] #gives me information for the response
list_o_json[0]['reactions']['paging']['next'] #returns a http link to the next set of reactions.
Any suggestions how I can collect then follow the "next" link, collect info then follow the next link etc. to the end of the node?
I'm using python-twitter in my Web Application to post tweets like this:
import twitter
twitter_api = twitter.Api(
consumer_key="BlahBlahBlah",
consumer_secret="BlahBlahBlah",
access_token_key="BlahBlahBlah",
access_token_secret="BlahBlahBlah",
)
twitter_api.PostUpdate("Hello World")
How do I retrieve all tweets posted to this account (including tweets that were previously posted to this account from other Twitter clients)? I want to do this so that I can delete them all by calling twitter_api.destroyStatus() on each tweet.
One approach could be like the following:
import twitter
api = twitter.Api(consumer_key='consumer_key',
consumer_secret='consumer_secret',
access_token_key='access_token',
access_token_secret='access_token_secret')
# get user data from credentials
user_data = api.VerifyCredentials()
user_id = long(user_data.id)
max_status_id = 0
# repeat until all tweets are deleted
while True:
# let us get 200 statuses per API call.
# trim_user helps improve performance by reducing size of return value
timeline_args = {'user_id': user_id, 'count': 200, 'trim_user': 'true'}
# if not first iteration, use max_status_id seen so far
if max_status_id != 0:
timeline_args['max_id'] = max_status_id
# Get statuses from user timeline
statuses = api.GetUserTimeline(**timeline_args)
#if no more tweets are left, then break the loop
if statuses is None or len(statuses) == 0:
break
for status in statuses:
# remember max_status_id seen so far
max_status_id = long(status.id) - 1
# delete the tweet with current status[id]
api.DestroyStatus(status.id)