Engineerの研鑽

メインはプログラミング系ブログ(本の要約とかもします)

質問はCONTACTやコメントでお願い致します。

【コピペでできるpython】seleniumを使ったインスタいいねの自動化

seleniumを使ったインスタいいねの自動化

こんにちわ!ゆきとです。

今日は先日の記事の続きです。

前回の記事のsqliteによるテーブルを作成した後に、pythonでインスタのいいねの自動化をしていきます。 

www.yukiyukiponsu.work

初心者の方でも理解できるようになるべく噛み砕いて説明するのでぜひご一読ください!

インスタ自動化後のイメージ 

*人間がいいねしているとインスタグラムに思わせるために、いいねを押すタイミングを遅くしたり速くしたりしています

youtu.be

プログラムの作成

フォルダとファイルの作成

ソースコードを作成していく前に完成後のファイル構造のイメージをつかんでください!

そしてこの構造どおりにフォルダ・ファイルを作ってください。

ファイル構造

likebot      (フォルダ)
├  .env      (ファイル)
├  like_hashtag.py   (ファイル)
├  db_init.py     (ファイル)

└ google_drive        (フォルダ)

       └  chromedriver(これは外部からインストールしたものをいれる)

chromedriverというのはseleniumでブラウザを操作するために必要なものです。各々の環境(windows, mac, linux)にあったものを公式サイトからダウンロードして、google_driveフォルダの下に配置しましょう!

詳しいダウンロード方法はおまけにて記載しているので、やり方がよくわからない人はそちらをみてくださいね。

必要なライブラリのインストール

seleniumのインストールpip install selenium
python-dotenvのインストールpip install python-dotenv

ソースコードの記述

それでは各々のソースコードを書いていきましょう!(コピペでOKです)

.env

USERNAME=インスタにログインするためのユーザの名前
PASSWORD=インスタにログインするためのパスワード

DBNAME=insta_post_contents.db

USERNAME, PASSWORDについてはコピペのまま実行しないでくださいね!

インスタにログインができないので笑

like_hashtag.py

from selenium import webdriver
from selenium.webdriver.chrome.options import Options # オプションを使うために必要
from selenium.common.exceptions import WebDriverException
from selenium.webdriver.common.action_chains import ActionChains
import time
import random

from dotenv import load_dotenv
# .envファイルの内容を読み込みます
load_dotenv()

import os

import sys

import sqlite3
import re

def login():
    driver.get('https://www.instagram.com/accounts/login/?source=auth_switcher')
    f=open('insta.txt','a')
    f.write("instagramにアクセスしました\n")
    f.close()
    time.sleep(1)
    username = os.environ['USERNAME']
    password = os.environ['PASSWORD']
    driver.find_element_by_name('username').send_keys(username)
    time.sleep(1)
    driver.find_element_by_name('password').send_keys(password)
    time.sleep(1)

	#ログインボタンを押す
    driver.find_element_by_class_name('L3NKy       ').click()
    time.sleep(random.randint(2, 5))
    f = open('insta.txt','a')
    f.write("instagramにログインしました\n")
    f.close()
    time.sleep(1)

def tagsearch(tag):
    instaurl = 'https://www.instagram.com/explore/tags/'
    driver.get(instaurl + tag)
    time.sleep(random.randint(2, 10))
    f = open('insta.txt','a')
    f.write("listtagより、tagで検索を行いました\n")
    f.close()
    time.sleep(1)

def clicknice():
    target = driver.find_elements_by_class_name('_9AhH0')[9]
    actions = ActionChains(driver)
    actions.move_to_element(target)
    actions.perform()
    f = open('insta.txt','a')
    f.write("最新の投稿まで画面を移動しました\n")
    f.close()
    time.sleep(1)

    dbname = os.environ["DBNAME"]

    try:
        driver.find_elements_by_class_name('_9AhH0')[0].click()
        time.sleep(random.randint(2, 10))
        f = open('insta.txt','a')
        f.write("投稿をクリックしました\n")
        f.close()
        time.sleep(1)
        post_text = driver.find_element_by_class_name("C4VMK")
        post_contain = post_text.find_elements_by_tag_name("span")[1].text
        post_contain_plane_format = re.sub('\s', '',post_contain)
        print(post_contain_plane_format)

        conn = sqlite3.connect(dbname)
        cur = conn.cursor()

        cur.execute('select * from instagramContents where post_content=?;', (post_contain_plane_format, ))
        print(cur.fetchall())

        #新しくいいねするものだけを処理
        if not cur.fetchall(): 
            driver.find_element_by_class_name('fr66n').click()
            f = open('insta.txt','a')
            f.write("投稿をいいねしました\n")
            f.close()
            time.sleep(1)
            cur.execute('INSERT INTO instagramContents(post_content) values(?)',(post_contain_plane_format, ))
            conn.commit()

        for i in range(random.randint(200, 300)):
                try:
                    driver.find_element_by_class_name('coreSpriteRightPaginationArrow').click()
                    f = open('insta.txt','a')
                    f.write("次の投稿へ移動しました\n")
                    f.close()
                    time.sleep(random.randint(random.randint(2, 5), random.randint(10, 15)))

                except WebDriverException:
                    f = open('insta.txt','a')
                    f.write("2つ目の位置でエラーが発生しました\n")
                    f.close()
                    time.sleep(5)
                    cur.close()
                    conn.close()

                try:
                    post_text = driver.find_element_by_class_name("C4VMK")
                    post_contain = post_text.find_elements_by_tag_name("span")[1].text
                    post_contain_plane_format = re.sub('\s', '',post_contain)
                    print(post_contain_plane_format)
                    cur.execute('select * from instagramContents where post_content=?;', (post_contain_plane_format,))
                    print(cur.fetchall())
                    if not cur.fetchall(): 
                        cur.execute('INSERT INTO instagramContents(post_content) values(?)',(post_contain_plane_format, ))
                        conn.commit()
                        #新しくいいねするものだけを処理
                        driver.find_element_by_class_name('fr66n').click()
                        f = open('insta.txt','a')
                        f.write("投稿にいいねしました\n")
                        f.close()
                        time.sleep(2)
                except WebDriverException:
                    f = open('insta.txt','a')
                    f.write("3つ目の位置でエラーが発生しました\n")
                    f.close()
                    cur.close()
                    conn.close()

                print("いいね回数 : ", i+1)

        cur.close()
        conn.close()

    except WebDriverException:
        f = open('insta.txt','a')
        f.write("エラーが発生しました\n")
        f.close()

        cur.close()
        conn.close()
        return

if __name__ == '__main__':
    taglist = ['かわいい女の子']  ####### ここに自分の好きなハッシュタグを記載 #######
    option = Options()
    # option.add_argument('--headless') 
    driver = webdriver.Chrome(options=option, executable_path='google_drive/chromedriver')
    time.sleep(1)
    login()
    tagsearch(random.choice(taglist))
    clicknice()
    driver.quit()
    sys.exit()

db_init.py

from dotenv import load_dotenv
# .envファイルの内容を読み込みます
load_dotenv()

import os

import sqlite3

dbname = os.environ["DBNAME"]
conn = sqlite3.connect(dbname)
cur = conn.cursor()

# instagramContentsというtableを作成してみる
cur.execute('CREATE TABLE instagramContents(id INTEGER PRIMARY KEY AUTOINCREMENT, post_content STRING);')
conn.commit()
conn.close()

ファイルの作成は完了です!

次に、前回の記事を参考にDBにテーブルを作りましょう!(詳しくは前回記事を参照)

pythonの実行python db_init.py

 上記のpythonを実行すると下記のようなファイル構造になります。

ファイル構造

likebot      
├  .env      
├  like_hashtag.py   
├  db_init.py   

├  insta_post_contents.db <= 追加される

└ google_drive     

       └  chromedriver

 このファイル構造の状態で、like_hashtag.pyを実行します。

pythonの実行

python like_hashtag.py

 この時、macでセキュリティエラーが出るかもしれませんが、問題ないのでそのまま実行を続けてください。(必要であればセキュリティエラーを取り除いてください)

 ここまでできれば最初の実行結果イメージのように動作します!

 お疲れ様でした!

感想

今日はseleniumを使ったインスタいいねの自動化を行いました。

 コード自体は非常にシンプルなものですが、それ以外で考えることが非常に多かったなと思いました。

 chromedriverのインストール、DBの作成、インストール・実行時のセキュリティ管理(警告が出た際に対応)など「コードを書いて実行する」以外の部分でやることが多々ありました。

 こういったコード以外の部分でつまることが多いので、皆さんも気をつけて。

 今日の記事の内容は以上です。

 今日もブログを読んでくださり誠にありがとうございます。

 それではまた後日!

おまけ

googledriveのインストール方法詳細

まずGoogle Chromeのバージョンを確認してください。 

google chromeの右上の3つの・が縦に並んでいるところをクリック

② 設定をクリック 

chromeについてをクリック 

①~③を行って頂くと、google chromeのバージョンが確認できます。

google driveインストールほうほう

先ほど調べたgoogle chromeのバージョンのものをダウンロードしてください。 自分のバージョンのChromeDriverがなければ、そのバージョンの次に古いバージョンの ChromeDriverを入れてください。 

上の写真のgoogle chromeバージョン : 86.0.4240.80に対応するChromeDriverが無いのでそれより一つ古いChromeDriver 86.0.4240.22をダウンロード してください。

 以上が、chromedriverのインストール方法です。