PythonでInstagramからパブリックVKに投稿をクロスポストする





まえがき



特に、Instagramアカウントを持っていないオンラインストアのターゲットオーディエンスは、VKの複製の出現に長い間興味を持っていたため、新しい市場に参入することにしました。 アイデアは良いのですが、ページには何百もの投稿がありますので、 ctrl + c ctrl + vは手動で作業したくありませんでした。また、猿の仕事のさらなる展望は印象的ではありませんでした。



インターネットには無料のソリューションがたくさんあると確信して、グーグル検索を始めました。 当然のことながら、検索結果の最初のページには、かなり広範な機能を備えた有料サービスがいっぱいです。 しかし、私にとっては、すべてのためだけに、すべての投稿をInstagramページから公開VKに転送し、その後同時にそれを補充する必要がありました。



適切なものが見つからなかったために、 ひどく見た目 が多かったため、 ヒキガエル絞殺して脚本を自分で書くことにしました。 Python言語を選択します。 シンプルで便利、不要なフリルなし、そしてスピードはこの問題では重要ではありません。



Instagram APIとVKのドキュメントは非常に詳細であり、タスクは複雑に見えません。 数晩、自分自身を解放した後、仕事に取り掛かりました。 最初のステップは、InstagramとVKの両方でトークンを取得することでした。 これに問題はなく、両方とも数分で届きました。



次に、私は最初の落とし穴を待っていました...



最初の20件の投稿のクロスポスト



驚いたことに、Instagramのポリシーを変更した後、ページの最後の20の投稿のみにjson辞書(写真へのリンク、投稿の説明、公開日など)を取得できることがわかりました。 それは2番目のタスクに適していました-時々新しい投稿で一般を更新します。 私には新しい出版物があまり頻繁に登場せず、20の投稿が非常に便利だからです。 最初にこのタスクを実行することが決定されました。



VKセッションを取得し、必要な変数を宣言します。



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 
      
      





次に、メイン関数を作成します。 始めるために、作業するデータの配列を取得します。



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





リクエストでは、角括弧の代わりにデータを挿入する必要があります。 ユーザー名でページIDを見つけることができます(例: ここ)



何かが返された場合は、先に進みます。



 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)
      
      





悔い改める
グローバル変数の操作は悪いことを知っていますが、スクリプトのサイズにより、複雑さを掘り下げることはできません



そのため、投稿の公開日が設定した日付よりも長い場合は、その公開日が名前(特にトートロジーに注意、スキップが重要)を持つフォルダーを作成します。 次は写真とビデオの数のチェックです。 きっとあなたはそれを取り付けることができます、私はただそれを必要としません。 作成したフォルダーに写真をアップロードします。 キャプションキーを使用して投稿の説明を取得し、 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   
      
      





フォルダー内の写真の数を特定し、それらをVKサーバーにアップロードし、投稿パラメーターに追加して、公開します。 パラメーターへの追加は、 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    
      
      





写真をVKサーバーに直接アップロードするには、 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))
      
      





2番目のタスクを整理しました。 スクリプトは、単独で実行することも、スケジュールに従って実行することもできます(たとえば、 cronで 、15分ごとに1回)。 そして今、他のすべての数百の投稿を転送する方法は?



ページ全体をラップ



スクリプトの一部は既に準備ができており、VKでの出版自体を担当していました。 すべての写真とそれらの説明を圧縮する方法を見つけることは残っています。 私はInstagramページのソースコードを解析することを気にせず、既成のソリューションを取りました。 実際、このようなプログラムは多数あると確信しています。最初に使用した無料の( 4K Stogram )を使用しました。 直感的なインターフェイスを使用すると、ページからすべての写真をすばやくダウンロードできます。 メニューには、投稿のすべての説明のエクスポートもあります。 「 * .txt 」形式が必要です。 すべての写真をフォルダー(1つの投稿-1つのフォルダー)に配置し、正規表現によって教科書からの投稿の説明を解析するだけです。



次のコードは、写真をフォルダーに分解するのに役立ちます。



 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
      
      





ここで重要なのは、公開時間です。公開時間は、複数の写真を1つのフォルダーに結合します。



それでは、すべてが簡単です。 各フォルダーを開き、すべての写真をサーバーにアップロードし、説明を添付して公開します。 VKの制限を忘れないでください。1日あたりの投稿数は50以下です。



 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
      
      





おそらく彼は最も簡単で最速の方法を採用しなかったかもしれませんが、結果は達成されました。 ご静聴ありがとうございました。govnokodスクリプトに関するすべての質問と重要なコメントに答える準備できています。



3つのスクリプト全体:



最初の20件の投稿のクロスポスト
 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()
      
      







写真をフォルダーで並べ替える
 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
      
      







すべての出版物をVKに投稿する
 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
      
      








All Articles