はじめに
Instagramで自動良いねに取り組みました。
色んな記事が出ているのですが、Instagramは仕様がどんどん変わるので、
既存の記事だとエラーが起きることが多く、修正してうまくできたので、こちらに共有します。
基本的な内容はこちらなどを参考にさせていただきました。
https://oretano.com/instagram-python-like
変更点①
この記事のうち、まずタグでの検索画面の中から投稿を選択するときのこちらのコードですが、
def clicknice():
target = driver.find_elements_by_class_name('_9AhH0')[10]
actions = ActionChains(driver)
ここのclass_nameの仕様が変わっており、
_9AhH0 → _aagw
に変えるとうまくいきました。
こちらが正しいバージョンです。
def clicknice():
target = driver.find_elements_by_class_name('_aagw')[10]
actions = ActionChains(driver)
変更点2
1つ目の投稿に良いねができて、次の投稿に移るこちらの部分ですが、
for i in range(random.randint(3, 5)):
try:
driver.find_element_by_class_name('coreSpriteRightPaginationArrow').click()
f = open('insta.txt','a')
f.write("次の投稿へ移動しました\n")
coreSpriteRightPaginationArrow
の引数だとうまくいかなかったので、こちらに変更しました。
for i in range(random.randint(3, 5)):
try:
driver.find_elements_by_xpath('//button[@class="_abl-"]')[2].click()
f = open('insta.txt','a')
f.write("次の投稿へ移動しました\n")
まとめコード
最後に、他のちいさな修正もして、うまくいったコードを載せておきます。
ライブラリが足りない場合は適宜インストールしてください。
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.common.exceptions import WebDriverException
from selenium.webdriver.common.action_chains import ActionChains
import time
import datetime
import bs4
import random
import chromedriver_binary
def now_time():
dt_now = datetime.datetime.now()
return dt_now.strftime('%m/%d %H:%M')+' '
#ログイン
username = 'usernameを入れてください'
password = 'passwordを入れてください'
#ハッシュタグは自分で好きなものを入れてください。
tagName = random.choice(['tag1','tag2','tag3'])
print(tagName)
#イイね数の設定
likedMax = 300
from webdriver_manager.chrome import ChromeDriverManager
driver = webdriver.Chrome (ChromeDriverManager().install())
driver.get('https://www.instagram.com/accounts/login/?source=auth_switcher')
print(now_time()+'instagramにアクセスしました')
time.sleep(1)
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_xpath('//*[@id="loginForm"]/div/div[3]').click()
time.sleep(3)
print(now_time()+'instagramにログインしました')
time.sleep(1)
#タグを検索
instaurl = 'https://www.instagram.com/explore/tags/'
driver.get(instaurl + tagName)
time.sleep(3)
print(now_time()+"tagで検索を行いました")
time.sleep(3)
#直近で投稿ページに移動
target = driver.find_elements_by_class_name('_aagw')[10]
actions = ActionChains(driver)
actions.move_to_element(target)
actions.perform()
print(now_time()+'最新の投稿まで画面を移動しました')
time.sleep(3)
#過去にイイねをしたか確認
def check_Like():
html = driver.page_source.encode('utf-8')
soup = bs4.BeautifulSoup(html, "lxml")
a = soup.select('span._aamw')
return not '取り消す' in str(a[0])
#直近の投稿にいいね
try:
driver.find_elements_by_class_name('_aagw')[9].click()
time.sleep(random.randint(3, 5))
print(now_time()+'投稿をクリックしました')
time.sleep(4)
if check_Like():
driver.find_element_by_class_name('_aamw').click()
print(now_time()+'投稿をいいね(1回目)')
time.sleep(random.randint(3, 5))
else:
print(now_time()+'いいね済みです')
except WebDriverException:
print(now_time()+'エラーが発生しました')
#その他の投稿にイイねをしていく
for i in range(likedMax-1):
try:
driver.find_elements_by_xpath('//button[@class="_abl-"]')[2].click()
print(now_time()+'次の投稿へ移動しました')
time.sleep(random.randint(3, 5))
except WebDriverException:
print(now_time()+'{}つ目の位置でエラーが発生しました'.format(i+2))
time.sleep(random.randint(4, 10))
try:
if check_Like():
driver.find_element_by_class_name('_aamw').click()
print(now_time()+'投稿をいいね({}回目)'.format(i+2))
time.sleep(random.randint(3, 5))
else:
print(now_time()+'いいね済みです')
except WebDriverException:
print(now_time()+'{}つ目の位置でエラーが発生しました'.format(i+3))
print(now_time()+'いいね終了')
driver.close()
driver.quit()
以上です。特にClass_nameなどは頻繁に変更されているようです。
うまく行かない場合はこういったエラーが出ます。
IndexError: list index out of range
その時は、以下のようにタグ検索画面で投稿を右クリックして「検証」ページに移り、
class部分を見て、変わっていないかをご確認ください。
以上です。ご質問はお気軽に。