From 00eacf0e8212a227c0bc50d2d3d68ff2974deb75 Mon Sep 17 00:00:00 2001 From: Vladimir Protsenko Date: Thu, 25 Nov 2021 08:07:20 +0000 Subject: [PATCH] Updated code for downloading photos. --- lab3.md | 160 +++++++++++++++++++++++--------------------------------- 1 file changed, 65 insertions(+), 95 deletions(-) diff --git a/lab3.md b/lab3.md index 219237f..fdf3cdb 100644 --- a/lab3.md +++ b/lab3.md @@ -6,103 +6,73 @@ ## 1. Скачивание фотографий из социальной сети -При выполнении данной лабораторной работы следует использовать пакет VK (не VK_api). -Установим данный пакет с помощью следующей команды. -```bash -$ pip install vk -``` -Необходимо создать приложение VK для того, чтобы получить доступ к данным. Для этого перейдем на страницу разработчиков VK и в разделе «Мои приложения» создадим новое приложение. Для дальнейшей работы нам потребуется ID приложения и Защищённый ключ. -Войдем в VK. - -```python -from urllib.request import urlretrieve -import vk, os, time, math -# Авторизация -login = '' -password = '' -vk_id = 'ID_ВАШЕГО_ПРИЛОЖЕНИЯ' -session = vk.AuthSession(app_id=vk_id, -user_login=login, user_password=password) -vkapi = vk.API(session) -``` - -Для удобства, входными данными можно указать ссылки на альбомы. Только целиком url не подойдёт, понадобится id хозяина альбома (группы или человека) и id самого альбома, которые и можно достать из ссылки. К примеру, в https://vk.com/album-54530371_212428070 id владельца (в данном случае сообщества) это -54530371, а id альбома – 212428070. Следует обратить внимание, если загружать из альбома сообщества, то «-» (дефис) перед id владельца обязателен. - -Получаем на вход ссылку на альбом, затем разбираем её и раскладываем по переменным `album_id` и `owner_id` соответствующие `id`. +При выполнении данной лабораторной работы будем использовать `vk_api` для выполнения запросов https://vk.com/dev/photos к социальной сети вконтакте. -Далее нужно получить количество фото, а также инициализировать переменные для статистики. +Код загрузки фотографий приведён ниже. -```python -#url = input("Введите url альбома: ") -url = "https://vk.com/album223007487_199949846" - -# Разбираем ссылку -album_id = url.split('/')[-1].split('_')[1] -owner_id = url.split('/')[-1].split('_')[0].replace('album', '') -photos_count = vkapi.photos.getAlbums( - owner_id=owner_id, - album_ids=album_id)[0][‘size’] - -counter = 0 # текущий счетчик -prog = 0 # процент загруженных -breaked = 0 # не загружено из-за ошибки -time_now = time.time() # время старта ``` - -Проблема при загрузке большого количества фотографий в том, что за один запрос нельзя забрать больше 1000 штук, в то время как в альбоме их может быть десяток тысяч. - -Процесс загрузки описывается следующим образом. - -```python - #Создадим каталоги -if not os.path.exists('saved'): - os.mkdir('saved') - -photo_folder = 'saved/album{0}_{1}'.format(owner_id, album_id) - -if not os.path.exists(photo_folder): - os.mkdir(photo_folder) - -# Подсчитаем, сколько раз нужно получать список фото, так как число получится не целое - округляем в большую сторону -for j in range(math.ceil(photos_count / 1000)): - photos = vkapi.photos.get( - owner_id=owner_id, - album_id=album_id, - count=1000, - offset=j*1000, - v=5.95)['items'] - - # Получаем список фото - for photo in photos: - counter += 1 - sizes = photo['sizes'] - s = photo['sizes'][0] - value_x = 0 - value_y = 0 - # выбираем самый большой размер - for size in sizes: - if value_x < size['width']: - value_x = size['width'] - s = size - - if value_y < size['height']: - value_y = size['height'] - s = size - - print(s['url']) - # Получаем адрес изображения - url_ = s['url'] - print('Загружаю фото № {} из {}. Прогресс: {}'.format(counter, photos_count, prog)) - prog = round(100/photos_count*counter, 2) - try: - # Загружаем и сохраняем файл - urlretrieve(url_, photo_folder + "/" + os.path.split(url_)[1]) - except Exception: - print('Произошла ошибка, файл пропущен.') - breaked += 1 - continue - time_for_dw = time.time() - time_now - print("\nВ очереди было {} файлов. Из них удачно загружено {} файлов, {} не удалось загрузить.") +import os +import sys +import vk_api +import urllib + +LOGIN = '' +PASSWORD = '' + +target_ids = [123124, -1212412] +# идентификаторы сообщества имеют отрицательные значения. + +def auth_handler(): + """ При двухфакторной аутентификации вызывается эта функция. + """ + # Код двухфакторной аутентификации + key = input("Enter authentication code: ") + # Если: True - сохранить, False - не сохранять. + remember_device = True + return key, remember_device + +def main(): + # ======= Открываем сессию с VK ======= + vk_session = vk_api.VkApi(LOGIN, PASSWORD, + auth_handler=auth_handler # функция для обработки двухфакторной аутентификации + ) + try: + vk_session.auth() + except vk_api.AuthError as error_msg: + print(error_msg) + #return + + vk = vk_session.get_api() + tools = vk_api.VkTools(vk_session) + + # ======= начинаем перебирать каждого пользователя ======= + for target_id in target_ids: + + # создаем директорию с именем пользователя, если нет + newpath = os.path.join(sys.path[0], id_user) + if not os.path.exists(newpath): + os.makedirs(newpath) + + # посылаем запрос к VK API, count свой, но не более 200 + + if target_id >= 0: + # Вариант 1 - скачать все фотографии пользователя + response = vk.photos.getAll(owner_id=int(target_id), count=3) + else: + # Вариант 2 - скачать все фотографии сообщества + response = tools.get_all("photos.getAll", 100, {'owner_id': target_id}) + + # работаем с каждой полученной фотографией + for i in range(len(response["items"])): + # берём ссылку на максимальный размер фотографии + photo_url = str(response["items"][i]["sizes"][len(response["items"][i]["sizes"]) - 1]["url"]) + + # скачиваем фото в папку с ID пользователя + urllib.urlretrieve(photo_url, newpath + '/' + str(response["items"][i]['id']) + '.jpg') + + +if __name__ == "__main__": + main() ``` ## 2. Кластеризация цветов на изображении @@ -289,4 +259,4 @@ ax.set_xlabel('X') ax.set_ylabel('Y') ax.set_zlabel('Z') plt.show() -``` \ No newline at end of file +```