Почему FlickrAPI зависает после получения результатов?

#python #web-scraping #flickr

Вопрос:

Я пытаюсь удалить изображения с Flickr с помощью FlickrAPI. Что происходит, так это то, что командная строка просто остается там, и после удаления URL-адресов изображений ничего не происходит. Это что-то вроде следующего: введите описание изображения здесь

После этого экрана ничего не происходит, он остается здесь в течение длительного времени, иногда где-то в диапазоне 1200 секунд или более.

Для очистки я использовал следующий код:

 def get_urls(search='honeybees on flowers', n=10, download=False):  t = time.time()  flickr = FlickrAPI(key, secret)  license = () # https://www.flickr.com/services/api/explore/?method=flickr.photos.licenses.getInfo  photos = flickr.walk(text=search, # http://www.flickr.com/services/api/flickr.photos.search.html  extras='url_o',  per_page=500, # 1-500  license=license,  sort='relevance')   if download:  dir = os.getcwd()   os.sep   'images'   os.sep   search.replace(' ', '_')   os.sep # save directory  if not os.path.exists(dir):  os.makedirs(dir)   urls = []  for i, photo in enumerate(photos):  if i lt; n:  try:  # construct url https://www.flickr.com/services/api/misc.urls.html  url = photo.get('url_o') # original size  if url is None:  url = 'https://farm%s.staticflickr.com/%s/%s_%s_b.jpg' %   (photo.get('farm'), photo.get('server'), photo.get('id'), photo.get('secret')) # large size   download  if download:  download_uri(url, dir)   urls.append(url)  print('%g/%g %s' % (i, n, url))  except:  print('%g/%g error...' % (i, n))   # import pandas as pd  # urls = pd.Series(urls)  # urls.to_csv(search   "_urls.csv")  print('Done. (%.1fs)' % (time.time() - t)   ('nAll images saved to %s' % dir if download else ''))  

Эта функция вызывается следующим образом:

 if __name__ == '__main__':  parser = argparse.ArgumentParser()  parser.add_argument('--search', type=str, default='honeybees on flowers', help='flickr search term')  parser.add_argument('--n', type=int, default=10, help='number of images')  parser.add_argument('--download', action='store_true', help='download images')  opt = parser.parse_args()   get_urls(search=opt.search, # search term  n=opt.n, # max number of images  download=opt.download) # download images  

Я несколько раз пытался просмотреть код функции, но, похоже, не могу понять, почему после очистки ничего не происходит, так как все остальное работает нормально.

Комментарии:

1. у вас есть per_page=500 , так что, возможно, он все еще запускает код для других изображений, но вы используете if i lt; n , чтобы пропустить отображение какой — либо информации-поэтому он все еще запускает код для 490 изображений, и вы ждете конца. Вы должны скорее использовать break для выхода из цикла, когда i gt;= n . ИЛИ вы должны использовать photos[:n] для работы только с n изображениями.

Ответ №1:

Я не могу запустить его, но я думаю, что вся проблема в том, что он получает информацию о 500 фотографиях — потому что у вас есть per_page=500 — и он запускает for цикл для всех 500 фотографий, и вам нужно дождаться конца for цикла.

Вы должны использовать break для выхода из этого цикла после n изображений

 for i, photo in enumerate(photos):  if i gt;= n:  break  else:   try:  # ...code ...  

Или просто вы должны использовать photos[:n] , и тогда вам не нужно проверять i lt; n

 for i, photo in enumerate(photos[:n]):  try:  # ...code ...  

В конце концов, вы должны использовать per_page=n


кстати:

Вы можете использовать os.path.join для создания пути

 dir = os.path.join(os.getcwd(), 'images', search.replace(' ', '_'))  

Если вы используете exist_ok=True in makedirs() , вам не нужно проверять if not os.path.exists(dir):

 if download:  dir = os.path.join(os.getcwd(), 'images', search.replace(' ', '_'))  os.makedirs(dir, exist_ok=True)  

Если вы используете enumerate(photos, 1) , то вы получаете значения 1,2,3,... вместо 0,1,2,...

Комментарии:

1. Спасибо, это действительно была ошибка. Я использовал эту if i gt;= n часть, потому что использование photos[:n] приведет к ошибке «генератор недоступен для подписки». В любом случае спасибо, что указали на ошибку!

2. тогда вам может понадобиться list(photos)[:n]