Postes croisés d'Instagram vers VK public en Python



Préface


J'ai décidé de pénétrer un nouveau marché, d'autant plus que le public cible de ma boutique en ligne, qui n'a pas de compte Instagram, s'intéresse depuis longtemps à l'apparition d'un doublon dans VK. L'idée est bonne, mais il y a des centaines de messages sur la page, respectivement, je ne voulais pas ctrl + c ctrl + v manuellement, plus les perspectives de travail avec les singes n'étaient pas impressionnantes.

Confiant que l'Internet regorge de solutions gratuites, j'ai commencé à googler. Naturellement, les premières pages de résultats de recherche regorgent de services payants, avec des fonctionnalités assez étendues. Mais pour moi, juste pour tout, j'ai dû transférer tous les messages de la page Instagram vers le VK public et ensuite le reconstituer simultanément.

Ne trouvant rien de convenable, peut - être qu'il regardait mal , il a été décidé d' étrangler le crapaud pour écrire le script lui-même. Choisissez le langage python. Simple, pratique, sans fioritures inutiles, et la vitesse n'est pas importante à cet égard.

La documentation sur Instagram api et VK est assez détaillée et la tâche ne semble pas compliquée. Après m'être libéré quelques soirs, je me mis au travail. La première étape consistait à obtenir des jetons sur Instagram et VK. Il n'y a eu aucun problème avec cela, les deux ont été reçus en quelques minutes.

Puis le premier écueil m'attendait ...

Crossposting les 20 premiers messages


À ma grande surprise, j'ai constaté qu'après des changements dans la politique Instagram, il était possible d'obtenir un dictionnaire json (liens vers les photos, description de l'article, date de publication ...) uniquement vers les 20 derniers articles de la page. Cela me convenait pour la deuxième tâche - mettre à jour le public avec de nouveaux messages de temps en temps. Parce que les nouvelles publications n'apparaissent pas si souvent avec moi et 20 messages sont assez pratiques. Il a été décidé de commencer cette tâche.

Nous obtenons la session VK et déclarons les variables nécessaires:

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  

Ensuite, nous écrivons la fonction principale. Pour commencer, nous obtenons un tableau de données avec lesquelles nous travaillerons:

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

Dans la demande, vous devez insérer vos données au lieu de crochets. Vous pouvez trouver l'identifiant de la page par nom d'utilisateur, par exemple, ici .

Si quelque chose nous est retourné, allez-y:

 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) 

Je me repens
Je sais que travailler avec des variables globales est mauvais, mais la taille du script vous permet de ne pas plonger dans la complexité

Donc, si la date de publication de l'article est supérieure à la date que nous avons fixée, créez un dossier dont le nom (attention à la tautologie, particulièrement sensible au saut) la date de sa publication. Viennent ensuite le nombre de photos et de vidéos. Vous pouvez certainement l'attacher, je n'en ai tout simplement pas besoin. Téléchargez des photos dans le dossier créé. Nous prenons la description du message à l'aide de la clé de légende et passons à la fonction 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    

Nous déterminons le nombre de photos dans le dossier, les téléchargeons sur le serveur VK, les ajoutons aux paramètres de publication et les publions en public. L'ajout aux paramètres se fait à l'aide de la fonction 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     

Et le téléchargement direct de photos sur le serveur VK est effectué par la fonction 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)) 

Nous avons réglé la deuxième tâche. Le script peut être exécuté seul ou selon un calendrier (par exemple, dans cron , une fois toutes les 15 minutes). Et maintenant, comment transférer toutes les autres centaines de messages?

Envelopper toute la page


Une partie du script est déjà prête, celle qui était responsable des publications elles-mêmes dans VK. Il reste à trouver un moyen de dégonfler toutes les photos et descriptions pour eux. Je n'ai pas pris la peine d'analyser les codes sources des pages Instagram et j'ai pris une solution toute faite. En fait, je suis sûr qu'il y a beaucoup de tels programmes, j'ai utilisé le premier gratuit ( 4K Stogram ). L'interface intuitive vous permet de gérer rapidement le téléchargement de toutes les photos de la page. Le menu propose également une exportation de toutes les descriptions des articles. Nous avons besoin d'un format " * .txt ". Il ne reste plus qu'à mettre toutes les photos dans des dossiers (un post - un dossier) et à analyser les descriptions des posts d'un manuel par expression régulière.

Le code suivant nous aidera à mettre les photos dans des dossiers:

 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 

Ici, le point clé est le temps de publication, qui combine plusieurs photos dans un dossier.

Eh bien, alors tout est simple. Nous ouvrons chaque dossier, téléchargeons toutes les photos sur le serveur, attachons la description et publions. N'oubliez pas la restriction VK: pas plus de 50 messages par jour:

 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 

Peut-être n’a-t-il pas suivi la voie la plus simple et la plus rapide, mais le résultat a été obtenu. Merci à tous pour votre attention, je suis prêt à répondre à toutes les questions et commentaires critiques sur mon script govnokod .

Les 3 scripts dans leur intégralité:

Crossposting les 20 premiers messages
 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() 


Trier les photos par dossiers
 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 


Publication sur VK de toutes les publications
 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/fr445408/


All Articles