2017-12-23

【Python x Selenium】Instagramでタグ検索し、取得した写真にすべていいねできる自動化ツールを作成しました


結論から言うと、Instagramで自動でいいねできるツールを作りました。
実装内容としては


  • ログインページで認証
  • 指定したタグで検索
  • 写真にいいね
  • 次へボタンが存在しなくなるまで永遠に指定したタグのいいねをし続ける

って感じです。




そもそもInstagramに何も興味なかった



普段全然興味なくて使っていないInstagram。
最後に使ったのは、浴衣姿の女子大生が見れると聞いてインストールしたとき以来でした。しかし実際に使ってみて、インストールした初月は水着美女や浴衣姿をたくさんと、女子大生のクッソどうでもいいスターバックスの投稿やらなんやらで、こんなくそアプリ穴を吹く紙にもならんなと思ったのでした。


Instagramに興味をもった理由



しかし、ここ最近再び興味を持ったのは、Instagramの自動ツールが割と需要があるという点でした。例えばLancersとかCloud Worksとか見ていると、ちらほらInstagramの自動化ツールの作成依頼が5-10万円くらいの単価で存在していたりとか。


あとは知り合いで実際にInstagramの自動化ツールを有料で利用している人がいたので、なるほどぉと思って興味を持ちました。


Instagramでマーケティングとは?


Instagramは結構マーケでも注目されているそうで、例えばこの辺の記事とか参考になりそうです




で、どういう風にInstagramをマーケティングで使っているんだろうなんて調べてみましたが、基本的には特定のタグで写真を投稿している人にいいねをすることで、集客を促進しているようですね。


例えば、たまたま#よみうりランドというコメントで検索した際に見つけた画像ですが、こんな感じです。




面白いですよね、よみうりランドに近いところのハッシュタグを利用して、そのように集客につなげるっていう戦法みたいですね。おそらくいいねすると近くにお店があることがわかるので、集客につながるんだと思います。


確かに、こうすると割と地域に応じたマーケとかもできそうで、よさそうですね。



商用化されているInstagramマーケティングツールを見ていると、


  • 特定のハッシュタグを選択
  • 定期実行プログラムにて、そのハッシュタグに対して投稿している人にたいしていいねを実行

というのが大半なようです。例えば、ハッシュライクというサイトでは、いいねを自動化させることができます。30日3600円で、指定したタグを設定し、定期実行でいいねをしてくれるようです。











ということで、この機能を今回は実装しました。


実装方法


この機能を実装するためには、当初二つ方法がありました。一つはInstagramの公式APIを利用してやる方法、もう一つはWebスクレイピングでごり押しする方法です。


前者を最初に試したのですが、どうやら2016年度にAPIの利用制限がかかり、自分の写真しか見れなくなるという、どうしようもないAPI仕様になってしまったようです。(Sandboxモードという、開発者向けお試し用)


これを無制限にするための審査が非常に面倒になりました。実際にAPIを利用したプロダクトを作成し、さらにその動画までつくってInstagramに送らなければいけないみたいです。しかもその審査もかなり厳しいようで、普通に利用するにはかなりハードルが高いようです。






できればこちらを利用したほうがよいのですが、ちょっと難しそうなので安定のSeleniumでごりおし作戦にしてみました。

環境


* Windows 10
* WSL
* Selenium
* Chrome Driver

ソースコード


usernameとpasswordを入れれば、おそらく動くかと。
日本語検索で少し困りましたが、URLのエンコーディング周りだったのが原因でした。
動くのですが、Webelementを複数取得したときに、Webelementの最初だけ取得する方法がわかりませんでした。わかる人がいらっしゃいましたら教えて下さい。

api.py

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import urllib.parse
import time

#Webdriver
browser = webdriver.Chrome(executable_path='/mnt/c/workspace/pydev/chromedriver.exe') #ここには任意のWebdriverを入れる

#URL

loginURL = "https://www.instagram.com/" #ログインする際のページ
tagSearchURL = "https://www.instagram.com/explore/tags/{}/?hl=ja" #.format()で{}の中の値を入れられるようになっている

#TagSearch

tagName = "よみうりランド" #タグの名前 #よみうりランド

#selectors
#ここには書くページのSelectorを選ぶ。x-pathもしくはcss selector

loginPath = '//*[@id="react-root"]/section/main/article/div[2]/div[2]/p/a' #xpath @https://www.instagram.com/
usernamePath = '//*[@id="react-root"]/section/main/article/div[2]/div[1]/div/form/div[1]/div/input' #xpath @https://www.instagram.com/
passwordPath = '//*[@id="react-root"]/section/main/article/div[2]/div[1]/div/form/div[2]/div/input' #xpath @https://www.instagram.com/

notNowPath = '//*[@id="react-root"]/div/div[2]/a[2]'

mediaSelector = 'div._e3il2' #表示されているメディアのwebelement @https://www.instagram.com/explore/tags/%E3%82%88%E3%81%BF%E3%81%86%E3%82%8A%E3%83%A9%E3%83%B3%E3%83%89/?hl=ja
likeXpath = '/html/body/div[3]/div/div[2]/div/article/div[2]/section[1]/a[1]'
nextPagerSelector = 'a.coreSpriteRightPaginationArrow' #次へボタン

#USER INFO

username = ""
password = "" 

#list

mediaList = []

#counter

likedCounter = 0

if __name__ == '__main__':

    #Login 
    browser.get(loginURL)
    time.sleep(3)
    browser.find_element_by_xpath(loginPath).click()
    time.sleep(3)
    usernameField = browser.find_element_by_xpath(usernamePath)
    usernameField.send_keys(username)
    passwordField = browser.find_element_by_xpath(passwordPath)
    passwordField.send_keys(password)
    passwordField.send_keys(Keys.RETURN)

    #Finished logging in. now at 
    time.sleep(3)
    encodedTag = urllib.parse.quote(tagName) #普通にURLに日本語は入れられないので、エンコードする
    encodedURL = tagSearchURL.format(encodedTag)
    print("encodedURL:{}".format(encodedURL))
    browser.get(encodedURL)

    #Finished tag search. now at https://www.instagram.com/explore/tags/%E8%AA%AD%E5%A3%B2%E3%83%A9%E3%83%B3%E3%83%89/?hl=ja
    time.sleep(3)
    browser.implicitly_wait(10)

    #写真を取得してクリックする

    mediaList = browser.find_elements_by_css_selector(mediaSelector)
    mediaCounter = len(mediaList)
    print("Found {} media".format(mediaCounter))

    for media in mediaList:
        media.click()

        # 次へボタンが表示されるまで
        while True:
            try:
                time.sleep(3)
                browser.find_element_by_xpath(likeXpath).click()
                browser.implicitly_wait(10)
                likedCounter += 1
                print("liked {} of {}".format(likedCounter,mediaCounter))
                browser.find_element_by_css_selector(nextPagerSelector).click()
            except:
                break #もう次へボタンが存在しない場合、エラーをはくのでそこで終了
        break #for文自体も終了させる

    print("You liked {} media".format(likedCounter))

ご依頼について

スクレイピングツール欲しい方は、@never_be_a_pmにご連絡お願いします。





注目の投稿

 PythonのTweepyを利用して、Twitter APIを利用している。 その中で、ハマったポイントをメモしておく。 まず、Searchに関して。 Twitter検索は、クライアントアプリ側では、全期間の検索が可能になっている。 一方で、APIを利用する際は、過去1週間しか...