Publicaciones cruzadas de Instagram en VK público en Python



Prólogo


Decidí ingresar a un nuevo mercado, especialmente porque el público objetivo de mi tienda en línea, que no tiene cuentas de Instagram, siempre ha estado interesado en la aparición de un duplicado en VK. La idea es buena, pero hay cientos de publicaciones en la página, respectivamente, no quería trabajar ctrl + c ctrl + v de forma manual, además, las perspectivas adicionales para el trabajo de mono no eran impresionantes.

Confiado en que Internet está lleno de soluciones gratuitas, comencé a buscar en Google. Naturalmente, las primeras páginas de resultados de búsqueda están llenas de servicios pagos, con funcionalidades bastante extensas. Pero para mí, solo para todo, tuve que transferir todas las publicaciones de la página de Instagram al VK público y luego reponerlas simultáneamente.

Al no encontrar nada adecuado, tal vez se veía mal , se decidió estrangular al sapo para escribir el guión él mismo. Eligió el lenguaje python. Simple, conveniente, sin lujos innecesarios, y la velocidad no es importante en este asunto.

La documentación en la API de Instagram y VK es bastante detallada y la tarea no parece complicada. Después de liberarme un par de noches, me puse a trabajar. El primer paso fue obtener tokens en Instagram y VK. No hubo problemas con esto, ambos fueron recibidos en un par de minutos.

Entonces la primera trampa me esperaba ...

Cruzando las primeras 20 publicaciones


Para mi sorpresa, descubrí que después de los cambios en la política de Instagram, era posible obtener un diccionario json (enlaces a fotos, descripción de la publicación, fecha de publicación ...) solo a las últimas 20 publicaciones de la página. Esto me convenía para la segunda tarea: actualizar al público con nuevas publicaciones de vez en cuando. Debido a que las nuevas publicaciones no aparecen tan a menudo conmigo y 20 publicaciones son bastante convenientes. Se decidió realizar esta tarea primero.

Obtenemos la sesión VK y declaramos las variables necesarias:

session = vk.Session( access_token='123abc') #  123abc   vk_api = vk.API(session, v='5.85') groupID = '12345678' #id  vk upload_url = vk_api.photos.getWallUploadServer(group_id=groupID)['upload_url'] #  vk   data = [] photo_id = 0 attachments = [] direct = 'C:/Users/jo/PycharmProjects/repost/foto' #     d = date(2019, 3, 21) # ,      data_parsing = int(time.mktime(d.timetuple())) #    unix  

A continuación, escribimos la función principal. Para comenzar, obtenemos una serie de datos con los que trabajaremos:

 answer = get( 'https://api.instagram.com/v1/users/[id_inst]/media/recent?access_token=[access_token]', verify=True).json() 

En la solicitud, debe insertar sus datos en lugar de corchetes. Puede encontrar la identificación de la página por nombre de usuario, por ejemplo, aquí .

Si nos devuelven algo, adelante:

 if answer: for x in answer['data']: #     json  global photo_id #     photo_id = 0 global attachments attachments = [] global data data = [] date_create = x['created_time'] # date_create    Unix if int(date_create) > data_parsing: n = 0 #     if not os.path.isdir(direct + '/' + date_create): #     os.makedirs(direct + '/' + date_create) if 'carousel_media' in x: #      for a in x['carousel_media']: li = list(a.keys()) #      if li.count('videos') == 0: #    ,      req.urlretrieve(a['images']['standard_resolution']['url'], "foto/" + date_create + "/" + str(n) + ".jpg") #       if x['caption'] is not None: #   text = str(x['caption']['text']) else: text = ' ' n = n + 1 post_foto(date_create, text) else: #      req.urlretrieve(x['images']['standard_resolution']['url'], "foto/" + date_create + "/0.jpg") if x['caption'] is not None: #   text = str(x['caption']['text']) else: text = ' ' post_foto(date_create, text) 

Me arrepiento
Sé que trabajar con variables globales es malo, pero el tamaño del script le permite no profundizar en la complejidad

Entonces, si la fecha de publicación de la publicación es mayor que la fecha que establecemos, cree una carpeta cuyo nombre (tautología de atención, especialmente sensible a omitir) sea la fecha de su publicación. A continuación, se verifica la cantidad de fotos y videos. Seguramente puedes adjuntarlo, simplemente no lo necesito. Sube fotos a la carpeta creada. Tomamos la descripción de la publicación usando la tecla de título y vamos a la función post_foto :

 def post_foto(date_create, text): quantity_foto = len([name for name in os.listdir(direct + "/" + date_create) if os.path.isfile(os.path.join(direct + "/" + date_create, name))]) #     append_attach(quantity_foto, date_create) params = {'attachments': attachments, 'message': text, 'owner_id': '-' + groupID, 'from_group': '1'} vk_api.wall.post(**params) #    VK    

Determinamos la cantidad de fotos en la carpeta, las subimos al servidor VK, las agregamos a los parámetros de publicación y la publicamos en público. La adición a los parámetros se realiza mediante la función append_attach :

 def append_attach(x, directory): #     for t in range(x): upload_foto(t, directory) global photo_id photo_id = data[t][0]['id'] global attachments attachments.append('photo' + str(data[t][0]['owner_id']) + '_' + str(photo_id)) #  id     

Y la carga directa de fotos al servidor VK se realiza mediante la función upload_foto :

 def upload_foto(num_foto, directory): #     request = requests.post(upload_url, files={'photo': open("foto/" + directory + "/" + str(num_foto) + ".jpg", "rb")}) params = {'server': request.json()['server'], 'photo': request.json()['photo'], 'hash': request.json()['hash'], 'group_id': groupID} global data data.append(vk_api.photos.saveWallPhoto(**params)) 

Resolvimos la segunda tarea. El script se puede ejecutar solo o según lo programado (por ejemplo, en cron , una vez cada 15 minutos). ¿Y ahora cómo transferir todos los otros cientos de publicaciones?

Ajustar toda la página


Parte del guión ya está listo, el responsable de las publicaciones en VK. Queda por encontrar una manera de desinflar todas las fotos y descripciones para ellos. No me molesté en analizar los códigos fuente de las páginas de Instagram y tomé una solución preparada. De hecho, estoy seguro de que hay muchos de esos programas, utilicé el primero gratuito ( 4K Stogram ). La interfaz intuitiva le permite hacer frente rápidamente a la descarga de todas las fotos de la página. El menú también tiene una exportación de todas las descripciones para publicaciones. Necesitamos un formato " * .txt ". Solo queda colocar todas las fotos en carpetas (una publicación - una carpeta) y analizar las descripciones de las publicaciones del libro de texto por expresión regular.

El siguiente código nos ayudará a colocar las fotos en carpetas:

 i = 0 for top, dirs, files in os.walk(os.getcwd()+"\\res\\"): for nm in files: if re.findall(r'\d\d\.\d\d\.\d\d', nm): old_file = os.path.join(top, nm) frq = re.findall(r'\d\d\d\d-\d\d-\d\d \d\d\.\d\d\.\d\d', str(nm)) frq = str(frq[0]) if not os.path.exists(os.getcwd()+"\\res\\" + frq): i = 0 os.makedirs(os.getcwd() + "\\res\\" + frq) new_file = os.path.join(os.getcwd() + "\\res\\" + frq, str(i)+'.jpg') os.rename(old_file, new_file) i = i+1 else: new_file = os.path.join(os.getcwd() + "\\res\\" + frq, str(i)+'.jpg') os.rename(old_file, new_file) i = i+1 

Aquí, el punto clave es el tiempo de publicación, que combina varias fotos en una carpeta.

Bueno, entonces todo es simple. Abrimos cada carpeta, subimos todas las fotos al servidor, adjuntamos la descripción y publicamos. No te olvides de la restricción de VK: no más de 50 publicaciones por día:

 f = open(os.getcwd() + "\input_opis\\gusi.txt", "rt", errors="ignore", encoding='utf-8') #     data = f.read() #  ,      result = re.findall(r'"([^\"]*)"', data, re.S) new_x = [el for el, _ in groupby(result)] #     dlina = new_x.__len__() i = 1 f.close() for top, dirs, files in os.walk(os.getcwd() + "\\res\\"): #   for nm in dirs: attachments = [] photo_id = 0 data = [] DIR = 'C:/Users/jo/PycharmProjects/repost/res/' + nm #     quantity_foto = len([name for name in os.listdir(DIR) if os.path.isfile(os.path.join(DIR, name))]) post_foto(quantity_foto, nm) attachments.reverse() #   params = {'attachments': attachments, 'message': new_x[dlina - i], 'owner_id': '-' + groupID, 'from_group': '1'} vk_api.wall.post(**params) i = i + 1 

Quizás no siguió el camino más fácil y rápido, pero el resultado se logró. Gracias a todos por su atención, estoy listo para responder todas las preguntas y comentarios críticos sobre mi script govnokod .

Los 3 guiones en su totalidad:

Cruzando las primeras 20 publicaciones
 from requests import get import urllib.request as req import vk import requests import os import time from datetime import date session = vk.Session( access_token='123abc') vk_api = vk.API(session, v='5.85') groupID = '12345678' #id  vk upload_url = vk_api.photos.getWallUploadServer(group_id=groupID)['upload_url'] #  vk   data = [] photo_id = 0 attachments = [] direct = 'C:/Users/jo/PycharmProjects/repost/foto' #     d = date(2019, 3, 21) # ,      data_parsing = int(time.mktime(d.timetuple())) #    unix  def upload_foto(num_foto, directory): #     request = requests.post(upload_url, files={'photo': open("foto/" + directory + "/" + str(num_foto) + ".jpg", "rb")}) params = {'server': request.json()['server'], 'photo': request.json()['photo'], 'hash': request.json()['hash'], 'group_id': groupID} global data data.append(vk_api.photos.saveWallPhoto(**params)) def append_attach(x, directory): #             for t in range(x): upload_foto(t, directory) global photo_id photo_id = data[t][0]['id'] global attachments attachments.append('photo' + str(data[t][0]['owner_id']) + '_' + str(photo_id)) #  id     def post_foto(date_create, text): quantity_foto = len([name for name in os.listdir(direct + "/" + date_create) if os.path.isfile(os.path.join(direct + "/" + date_create, name))]) #     append_attach(quantity_foto, date_create) params = {'attachments': attachments, 'message': text, 'owner_id': '-' + groupID, 'from_group': '1'} vk_api.wall.post(**params) #    VK    def get_all(): answer = get( 'https://api.instagram.com/v1/users/12345678/media/recent?access_token=123abc', verify=True).json() #     instagram if answer: for x in answer['data']: #     json  global photo_id #     photo_id = 0 global attachments attachments = [] global data data = [] date_create = x['created_time'] # date_create    Unix if int(date_create) > data_parsing: n = 0 #     if not os.path.isdir(direct + '/' + date_create): #     os.makedirs(direct + '/' + date_create) if 'carousel_media' in x: #      for a in x['carousel_media']: li = list(a.keys()) #      if li.count('videos') == 0: #    ,      req.urlretrieve(a['images']['standard_resolution']['url'], "foto/" + date_create + "/" + str(n) + ".jpg") #       if x['caption'] is not None: #   text = str(x['caption']['text']) else: text = ' ' n = n + 1 post_foto(date_create, text) else: #      req.urlretrieve(x['images']['standard_resolution']['url'], "foto/" + date_create + "/0.jpg") if x['caption'] is not None: #   text = str(x['caption']['text']) else: text = ' ' post_foto(date_create, text) get_all() 


Ordenar fotos por carpetas
 import re import os i = 0 for top, dirs, files in os.walk(os.getcwd()+"\\res\\"): for nm in files: if re.findall(r'\d\d\.\d\d\.\d\d', nm): old_file = os.path.join(top, nm) frq = re.findall(r'\d\d\d\d-\d\d-\d\d \d\d\.\d\d\.\d\d', str(nm)) frq = str(frq[0]) if not os.path.exists(os.getcwd()+"\\res\\" + frq): i = 0 os.makedirs(os.getcwd() + "\\res\\" + frq) new_file = os.path.join(os.getcwd() + "\\res\\" + frq, str(i)+'.jpg') os.rename(old_file, new_file) i = i+1 else: new_file = os.path.join(os.getcwd() + "\\res\\" + frq, str(i)+'.jpg') os.rename(old_file, new_file) i = i+1 


Publicar en VK todas las publicaciones
 import os import vk import requests import re from itertools import groupby session = vk.Session( access_token='123abc') vk_api = vk.API(session, v='5.85') groupID = '12345678' upload_url = vk_api.photos.getWallUploadServer(group_id=groupID)['upload_url'] data = [] photo_id = 0 attachments = [] def upload_foto(num_foto, direc): request = requests.post(upload_url, files={'photo': open('res/' + direc + "/" + str(num_foto) + ".jpg", "rb")}) params = {'server': request.json()['server'], 'photo': request.json()['photo'], 'hash': request.json()['hash'], 'group_id': groupID} global data data.append(vk_api.photos.saveWallPhoto(**params)) def post_foto(x, direc): for i in range(x): upload_foto(i, direc) global photo_id photo_id = data[i][0]['id'] global attachments attachments.append('photo' + str(data[i][0]['owner_id']) + '_' + str(photo_id)) f = open(os.getcwd() + "\input_opis\\gusi.txt", "rt", errors="ignore", encoding='utf-8') #     data = f.read() #  ,      result = re.findall(r'"([^\"]*)"', data, re.S) new_x = [el for el, _ in groupby(result)] #     dlina = new_x.__len__() i = 1 f.close() for top, dirs, files in os.walk(os.getcwd() + "\\res\\"): #   for nm in dirs: attachments = [] photo_id = 0 data = [] DIR = 'C:/Users/jo/PycharmProjects/repost/res/' + nm #     quantity_foto = len([name for name in os.listdir(DIR) if os.path.isfile(os.path.join(DIR, name))]) post_foto(quantity_foto, nm) attachments.reverse() #   params = {'attachments': attachments, 'message': new_x[dlina - i], 'owner_id': '-' + groupID, 'from_group': '1'} vk_api.wall.post(**params) i = i + 1 

Source: https://habr.com/ru/post/445408/


All Articles