Автоматическое обновление фотографии профиля Вконтакте

от автора

Код для обновления фотографии профиля Вконтакте с помощью VK API. Рассмотрим работу с капчей и загрузим код на сервер для автоматического обновления фотографии.
image

Необходимые библиотеки

Устанавливаем библиотеку vk_api для работы с VK API для Python: pip install vk_api

Пример работы vk_api

import vk_api  #Логин (номер телефона) и пароль от профиля ВК  vk_session = vk_api.VkApi('login', 'password') vk_session.auth()  vk = vk_session.get_api()  #Опубликовать пост на своей странице с текстом 'Hello world!' vk.wall.post(message='Hello world!')  

Импортируем необходимые библиотеки

import os import time import random import requests  import vk_api  from vk_api.utils import get_random_id from urllib import urlretrieve 

Авторизация

Авторизация в ВК с помощью API

vk_session = vk_api.VkApi('+7999132****', '*********') vk_session.auth()  vk = vk_session.get_api() 

Загрузка изображений

Загружаем изображения на сервер ВКонтакте.
photos.getOwnerPhotoUploadServer() возвращает адрес сервера для загрузки главной фотографии на страницу пользователя.

url = vk.photos.getOwnerPhotoUploadServer()['upload_url'] 

Для загрузки изображения на сервер ВКонтакте надо передать файл на адрес upload_url, полученный в предыдущем пункте, сформировав POST-запрос с полем photo.

#Изображения находятся в папке images images = os.listdir("images")  photo = [] for image in images:     request = requests.post(url, files={'photo': open('images/'+image, 'rb')}).json()     photo.append(request['photo']) 

Сохраним значения сервера и хеша. Они понадобятся для обновления фотографии профиля.

server = request['server']  hash = request['hash'] 

Обновление фотографии профиля

photos.saveOwnerPhoto() сохраняет фотографию пользователя.

#Выбираем рандомную фотографию и меняем фотографию профиля  x = random.randint(0, len(photo)-1) vk.photos.saveOwnerPhoto(server = server, hash = hash, photo = photo[x]) 

После обновления фотографии на стену добавляется пост с этой фотографией. Если не удалить эти посты, то лента друзей будет забита постами про ваше обновление аватарки.

posts = vk.wall.get() post_id = posts["items"][0]["id"] vk.wall.delete(post_id = post_id) 

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

y = 0 while(True):     x = random.randint(0, len(photo)-1)     while(x == y):         x = random.randint(0, len(photo)-1)     y = x     #x и y используется для того, чтобы одна фотография не повторялась 2 раза подряд          vk.photos.saveOwnerPhoto(server = server, hash = hash, photo = photo[x])      posts = vk.wall.get()     post_id = posts["items"][0]["id"]     vk.wall.delete(post_id = post_id)           #Удаляем предыдущую фотографию      photos = vk.photos.getAll()     if (photos['count']>1):         photo_id = photos["items"][1]["id"]         vk.photos.delete(photo_id = photo_id)          time.sleep(60) #Задержка 60 сек. 

Полный код

import os import time import random import requests  import vk_api  from vk_api.utils import get_random_id from urllib import urlretrieve  vk_session = vk_api.VkApi('+7999132****', '***********') vk_session.auth()  vk = vk_session.get_api()  images = os.listdir("images")  url = vk.photos.getOwnerPhotoUploadServer()['upload_url']  photo = [] for image in images:     request = requests.post(url, files={'photo': open('images/'+image, 'rb')}).json()     photo.append(request['photo'])  server = request['server']  hash = request['hash']  y = 0 while(True):     x = random.randint(0, len(photo)-1)     while(x == y):         x = random.randint(0, len(photo)-1)     y = x                     vk.photos.saveOwnerPhoto(server = server, hash = hash, photo = photo[x])      posts = vk.wall.get()     post_id = posts["items"][0]["id"]     vk.wall.delete(post_id = post_id)            photos = vk.photos.getAll()     if (photos['count']>1):         photo_id = photos["items"][1]["id"]         vk.photos.delete(photo_id = photo_id)              time.sleep(60) 

Но после несколькольких десятков обновлений фотографии профиля выйдет ошибка

Captcha: Captcha needed

Давайте разберемся как работать с капчей в VK API.

Работа с captcha

В методе vk_api.VkApi() уже реализована работа с капчей. Необходимо кроме логина и пароля передать функцию обработки капчи captcha_handler.
Изменяем vk_session

vk_session = vk_api.VkApi('+7999132****', '**********', captcha_handler=captcha_handler) 

Добавляем функцию captcha_handler(captcha), которая принимает адресс капчи, отправляет изображение капчи в сообщения пользователя и ждёт сообщение с капчей от пользователя.

def captcha_handler(captcha):          #Получаем адресс капчи     captcha_url = captcha.get_url()           #Сохраняем изображение капчи на компьютер     urlretrieve(captcha_url, "captcha.jpg")          #Получаем ключ (send_captcha() см. далее)     key = send_captcha(captcha_url)          #Отправляем ключ (текст) капчи     return captcha.try_again(key) 

Функция для отправки сообщений с изображением капчи пользователю.
Методы messages не доступны для пользователя с сервера, поэтому надо создать группу и получить token.

  1. Создаём группу/публичную страницу
  2. Управление => Работа с API => Создать ключ
  3. Выбираем:
    • Разрешить приложению доступ к сообщениям сообщества
    • Разрешить приложению доступ к фотографиям сообщества
  4. Копируем ключ

    Так же надо включить Сообщения в настройках группы (Управление => Сообщения) и разрешить сообщения (в меню группы)

    def send_captcha(captcha_url):     #token (ключ) группы     token = "КЛЮЧ"          vk_session = vk_api.VkApi(token = token)     vk = vk_session.get_api()          #Получаем адрес капчи     url = vk.photos.getMessagesUploadServer()['upload_url']          #Загружаем изображение на сервер ВКонтакте      request = requests.post(url, files={'photo': open("captcha.jpg", 'rb')}).json()          #Сохраняем фотографию     photo = vk.photos.saveMessagesPhoto(server=request['server'],                                         photo = request['photo'],                                         hash = request['hash'])          attachment = 'photo{}_{}'.format(photo[0]['owner_id'], photo[0]['id'])          #Отправляем сообщение     vk.messages.send(         user_id = ВАШ_ID,         attachment = attachment,         random_id=get_random_id())          #Удаляем капчу     os.remove("captcha.jpg")          #Ждем ответа     key = ''     while (key == ''):         #Получаем первый в списке диалог         messages = vk.messages.getDialogs()['items'][0]                  #Если к сообщению не прикреплено изображение, то значит это ключ          if 'attachments' not in messages['message'].keys():             key = messages['message']['body']     return key 

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

    Полный код

    import os import time import random import requests  import vk_api  from vk_api.utils import get_random_id from urllib import urlretrieve  def captcha_handler(captcha):          captcha_url = captcha.get_url()          urlretrieve(captcha_url, "captcha.jpg")          key = send_captcha(captcha_url)          print(key)     return captcha.try_again(key)  def send_captcha(captcha_url):     token = "КЛЮЧ"          vk_session = vk_api.VkApi(token = token)     vk = vk_session.get_api()          url = vk.photos.getMessagesUploadServer()['upload_url']          request = requests.post(url, files={'photo': open("captcha.jpg", 'rb')}).json()          photo = vk.photos.saveMessagesPhoto(server=request['server'],                                         photo = request['photo'],                                         hash = request['hash'])          attachment = 'photo{}_{}'.format(photo[0]['owner_id'], photo[0]['id'])          vk.messages.send(         user_id=ВАШ_ID,         attachment = attachment,         random_id=get_random_id())          os.remove("captcha.jpg")          key = ''     while (key == ''):         messages = vk.messages.getDialogs()['items'][0]         if 'attachments' not in messages['message'].keys():             key = messages['message']['body']     return key  vk_session = vk_api.VkApi('+7999132****', '*********', captcha_handler=captcha_handler) vk_session.auth()  vk = vk_session.get_api()  images = os.listdir("images")  url = vk.photos.getOwnerPhotoUploadServer()['upload_url']  photo = [] for image in images:     request = requests.post(url, files={'photo': open('images/'+image, 'rb')}).json()     photo.append(request['photo'])  server = request['server']  hash = request['hash']  y = 0 while(True):     x = random.randint(0, len(photo)-1)     while(x == y):         x = random.randint(0, len(photo)-1)     y = x                     vk.photos.saveOwnerPhoto(server = server, hash = hash, photo = photo[x])      posts = vk.wall.get()     post_id = posts["items"][0]["id"]     vk.wall.delete(post_id = post_id)            photos = vk.photos.getAll()     if (photos['count']>1):         photo_id = photos["items"][1]["id"]         vk.photos.delete(photo_id = photo_id)              print("Successfully", x)     time.sleep(60) 

    Для круглосуточного выполнения кода я использую VPS хостинг. Загружаю изображения и выполняю код на сервере.
    Код на github
    Если есть вопросы пишите в коментариях или в ЛС.


ссылка на оригинал статьи https://habr.com/ru/post/464285/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *