instagramをスクレイピングしたいけど、フォロワー取得するにはログインが必要
フォロワーはポップアップウィンドウをスクロールしないと見れない
→なのでSeleniumを使う
Seleniumについてはこちらのドキュメントを参照
環境
- Python3(3.7系)
- Selenium
- Chromedriver
- beatutifulsoup4(4.7.1以上推奨)
スクリプト(2019年6月確認)
sample.py
# coding:utf-8
# コマンドライン引数で指定したinstagramerのフォロワーをSeleniumで取得する
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import bs4
import pandas as pd
import time
import random
import sys
def main():
username = sys.argv[1]
print("start crawling follower of " + username)
# chromedriverのファイル場所はよしなに書き換えてください
driver = webdriver.Chrome('./chromedriver')
driver.get('https://www.instagram.com/accounts/login/?source=auth_switcher')
time.sleep(2)
# login
id = driver.find_element_by_name("username")
id.send_keys("YOUR USERNAME")
password = driver.find_element_by_name("password")
password.send_keys("YOUR PASSWORD")
password.send_keys(Keys.RETURN)
time.sleep(3)
driver.get('https://www.instagram.com/' + username + '/')
time.sleep(3)
follower_button = driver.find_elements_by_css_selector("li.Y8-fY")[1]
follower_button.click()
time.sleep(3)
dialog = driver.find_element_by_css_selector("div.isgrP")
# scroll popup window
# 2300人ほどのユーザーが取れる
for i in range(200):
driver.execute_script("arguments[0].scrollTop = arguments[0].scrollHeight", dialog)
time.sleep(random.randint(500,1000)/1000)
page_url = driver.page_source
soup = bs4.BeautifulSoup(page_url,"lxml")
elm = soup.find_all("a", {"class": "FPmhX notranslate _0imsa"})
followers = []
for e in elm:
followers.append(e.text)
df = pd.Series(followers)
df.to_csv("insta_followers_of_" + username + ".csv")
print("csv file is created.")
driver.close()
if __name__ == '__main__':
main()
sleepを挟んでJSの読み込みを待ってあげないとNo such element exceptionが発生するので、こまめに挟んであげています。
ただしSeleniumの場合はsleepではなくWebDriverWaitの使用が普通のようなので、そちらを使ってもいいと思います。参考
実行例
python sample.py masami_nagasawa
ポップアップウィンドウのスクロールは以下のコードで実行しています。
range()の引数でスクロールする回数を設定しています。
200回スクロールして2300人ぐらい取れました.
取得したい人数に応じて数字を調整してください。
for i in range(200):
driver.execute_script("arguments[0].scrollTop = arguments[0].scrollHeight", dialog)
time.sleep(random.randint(500,1000)/1000)