はい、皆さんこんばんは。前回、インスタの自動フォローツールを作成しました。見ていない方は是非こちらから見ていただけると嬉しいです。んで、その続編として、フォロー解除ツールも作っていこうと思います。
1-1 コード
自動フォロー解除のコードはこちらです。
from time import sleep
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
def get_user_input():
try:
username = input("アンフォロー対象のユーザー名を入力してください: ")
unfollow_interval = int(input("フォローを外す時間間隔(秒)を指定してください: "))
headless_input = input("ヘッドレスモードで実行しますか? (yes/no): ").strip().lower()
headless = headless_input == "yes"
unfollow_count = int(input("アンフォローするアカウントの数を指定してください: "))
return username, unfollow_interval, headless, unfollow_count
except Exception as e:
print(f"入力エラー: {e}")
return "", 0, False, 0
class InstaUnfollower:
def __init__(self, driver_path, headless):
try:
chrome_options = Options()
if headless:
chrome_options.add_argument("--headless")
chrome_options.add_argument("--disable-gpu")
chrome_options.add_argument("--window-size=1920x1080")
self.driver = webdriver.Chrome(service=Service(executable_path=driver_path), options=chrome_options)
except Exception as e:
print(f"ドライバ初期化エラー: {e}")
def add_cookies(self, sessionid, csrftoken):
try:
cookies = [
{'name': 'sessionid', 'value': sessionid, 'domain': '.instagram.com'},
{'name': 'csrftoken', 'value': csrftoken, 'domain': '.instagram.com'}
]
for cookie in cookies:
self.driver.add_cookie(cookie)
except Exception as e:
print(f"クッキー追加エラー: {e}")
def login(self, url, sessionid, csrftoken):
try:
self.driver.get(url)
sleep(5)
self.add_cookies(sessionid, csrftoken)
self.driver.refresh()
sleep(5)
except Exception as e:
print(f"ログインエラー: {e}")
def get_followers(self, username):
try:
self.driver.get(f"https://www.instagram.com/{username}/followers/")
sleep(25)
modal_xpath = self.get_valid_xpath(['/html/body/div[7]/div[1]/div/div[2]/div/div/div/div/div[2]/div/div/div[3]', '/html/body/div[6]/div[1]/div/div[2]/div/div/div/div/div[2]/div/div/div[3]'])
if modal_xpath:
self.scroll_modal(modal_xpath)
followers = self.extract_usernames_from_modal()
return followers
else:
print("有効なフォロワーモーダルのXPathが見つかりませんでした。")
return []
except Exception as e:
print(f"フォロワー取得エラー: {e}")
return []
def get_following(self, username):
try:
self.driver.get(f"https://www.instagram.com/{username}/following/")
sleep(25)
modal_xpath = self.get_valid_xpath(['/html/body/div[7]/div[1]/div/div[2]/div/div/div/div/div[2]/div/div/div[4]', '/html/body/div[6]/div[1]/div/div[2]/div/div/div/div/div[2]/div/div/div[4]'])
if modal_xpath:
self.scroll_modal(modal_xpath)
following = self.extract_usernames_from_modal()
return following
else:
print("有効なフォロー中モーダルのXPathが見つかりませんでした。")
return []
except Exception as e:
print(f"フォロー中取得エラー: {e}")
return []
def get_valid_xpath(self, xpaths):
for xpath in xpaths:
for _ in range(3):
try:
self.driver.find_element(By.XPATH, xpath)
return xpath
except:
sleep(2)
continue
return None
def scroll_modal(self, modal_xpath):
try:
modal = self.driver.find_element(By.XPATH, modal_xpath)
last_height = self.driver.execute_script("return arguments[0].scrollHeight", modal)
while True:
self.driver.execute_script("arguments[0].scrollTop = arguments[0].scrollHeight", modal)
sleep(2)
new_height = self.driver.execute_script("return arguments[0].scrollHeight", modal)
if new_height == last_height:
break
last_height = new_height
except Exception as e:
print(f"スクロールエラー: {e}")
def extract_usernames_from_modal(self):
try:
usernames = []
elements = self.driver.find_elements(By.CSS_SELECTOR, "a.notranslate._a6hd")
for element in elements:
usernames.append(element.text)
return usernames
except Exception as e:
print(f"ユーザー名抽出エラー: {e}")
return []
def get_username_from_xpath(self, index):
xpaths = [
f'/html/body/div[7]/div[1]/div/div[2]/div/div/div/div/div[2]/div/div/div[4]/div[1]/div/div[{index}]/div/div/div/div[2]/div/div/div/div/div/a/div/div/span',
f'/html/body/div[6]/div[1]/div/div[2]/div/div/div/div/div[2]/div/div/div[4]/div[1]/div/div[{index}]/div/div/div/div[2]/div/div/div/div/div/a/div/div/span'
]
for xpath in xpaths:
for _ in range(3):
try:
element = self.driver.find_element(By.XPATH, xpath)
return element.text
except:
sleep(2)
continue
return None
def get_unfollow_button_xpath(self, index):
xpaths = [
f'/html/body/div[7]/div[1]/div/div[2]/div/div/div/div/div[2]/div/div/div[4]/div[1]/div/div[{index}]/div/div/div/div[3]/div/button',
f'/html/body/div[6]/div[1]/div/div[2]/div/div/div/div/div[2]/div/div/div[4]/div[1]/div/div[{index}]/div/div/div/div[3]/div/button'
]
for xpath in xpaths:
for _ in range(3):
try:
self.driver.find_element(By.XPATH, xpath)
return xpath
except:
sleep(2)
continue
return None
def unfollow_users_from_following_page(self, username, followers, unfollow_interval, unfollow_count, exceptions):
try:
sleep(3)
unfollowed = 0
index = 1
while unfollowed < unfollow_count:
user = self.get_username_from_xpath(index)
if user and user not in followers and user not in exceptions:
unfollow_button_xpath = self.get_unfollow_button_xpath(index)
if unfollow_button_xpath:
unfollow_button = self.driver.find_element(By.XPATH, unfollow_button_xpath)
if unfollow_button.text in ["フォロー中", "Following"]:
unfollow_button.click()
sleep(1)
confirm_button_xpath = self.get_valid_xpath(["//button[text()='フォローをやめる']", "//button[text()='Unfollow']"])
if confirm_button_xpath:
confirm_button = self.driver.find_element(By.XPATH, confirm_button_xpath)
confirm_button.click()
sleep(unfollow_interval)
unfollowed += 1
index += 1
self.driver.quit()
except Exception as e:
print(f"フォロー中ページからのアンフォロー処理エラー: {e}")
if __name__ == "__main__":
sessionid = "56212316015%3AcLlyPoM07Y60Lb%3A20%3AAYf_BNXK_lLxdbFAkAY_YMreVtsvhDUSUj9MLmNtzA"
csrftoken = "V7Ld2XcJL714piRUrvunpole7uH2rFcv"
chrome_driver_path = r"/usr/local/bin/chromedriver-linux64/chromedriver"
username, unfollow_interval, headless, unfollow_count = get_user_input()
bot = InstaUnfollower(driver_path=chrome_driver_path, headless=headless)
bot.login(url="https://www.instagram.com/", sessionid=sessionid, csrftoken=csrftoken)
followers = bot.get_followers(username)
following = bot.get_following(username)
unfollow_list = list(set(following) - set(followers))
print("アンフォロー対象:")
for i, user in enumerate(unfollow_list, start=1):
print(f"{i}. {user}")
exceptions_input = input("例外に追加するユーザーの番号をカンマ区切りで入力してください(例: 1,3,5): ")
exceptions = []
try:
exception_indices = [int(index.strip()) - 1 for index in exceptions_input.split(',')]
for index in exception_indices:
if 0 <= index < len(unfollow_list):
exceptions.append(unfollow_list[index])
else:
print(f"無効な番号: {index + 1}")
except ValueError:
print("無効な入力です。番号をカンマ区切りで入力してください。")
# フォロー解除を実行
bot.unfollow_users_from_following_page(username, followers, unfollow_interval, unfollow_count, exceptions)
print("処理が完了しました。")
前回と同じようにcookie(sessionid,csrftoken)を打ち込んでください。基本的にはここまでしたらもう使えます。ですが尺が足りなさすぎるので機能などを解説します。
ここではこのコードでは何ができるかについてを解説します。
ここはまあ一応自動検出してできるようにできたんですがそこまでするのはちょっと面倒だったのでこの機能が欲しい場合は改造してください。まあ別にそんな不便ではないので問題ないです。どうせcookie情報をそれぞれ分けて書くのでusernameのinputに最初からアンフォロー対象のユーザー名入れておくのもありです。
フォロー解除が早すぎると自動化を検出されてしまうのでフォロー解除の時間間隔を設定できるようにしました。目安などは一概には言えませんが私は600秒あたりで使用しています。
これも検出対策です。多すぎると検出を食らうので控えめにしてください。目安は150-200くらいです。
デバッグ用です。何もしないのであれば有効化すれば良いと思います。
そんな感じです。エラーが出た場合は適宜修正お願いします。インスタの要素は良く変更されるのでxpathのモーダル確認したほうが良いかもです。
ご視聴ありがとうございました。