スクレイピングでTwitter, Instagramのフォロー/フォロワー数などを取得

はじめに

本稿は以下のような人向けです。

  • Twitter, Instagramのフォロー/フォロワー/投稿数取得を自動化したい
  • API連携をしてまでやるほど大規模なものじゃない。手間をかけず実装したい
  • 少数のユーザーを対象にしたもので、多くのリクエストを送ったりしない

動作確認環境

  • Python 3.5.2
  • beautifulsoup4 (4.6.0)

実装

Twitterは普通にDOMを抜き出し、Instagramはjavascriptを抜き出しました。
request時のエラーハンドリングや、DOMが変わってしまった時の対策等は書いてませんが、
サービスに載せる際にはそのあたりも考えておくと良いと思います。

コードではフォロー数とフォロワー数しか取得していませんが、
取得部分を変更すれば投稿数やいいね数なども取れると思います。

social_medias.py
import json
import re
import requests
from typing import Dict

from bs4 import BeautifulSoup

class SocialMedias():

    @classmethod
    def get_statuses(cls) -> Dict:
        statuses = {}

        statuses['instagram'] = cls.__get_instagram_statuses('https://www.instagram.com/nyakuro/')
        statuses['twitter'] = cls.__get_twitter_statuses('https://twitter.com/nyakuro')
        return statuses

    @classmethod
    def __get_twitter_statuses(cls, url: str) -> Dict:
        statuses = {}

        # ToDo: error handling
        response = requests.get(url)
        soup = BeautifulSoup(response.content, 'lxml')

        # get follow count
        content = cls.__get_element_by_class(soup, 'ProfileNav-item--following')
        statuses['following_count']\
            = int(cls.__get_element_by_class(content, 'ProfileNav-value').string.replace(',', ''))

        # get follower count
        content = cls.__get_element_by_class(soup, 'ProfileNav-item--followers')
        statuses['follower_count']\
            = int(cls.__get_element_by_class(content, 'ProfileNav-value').string.replace(',', ''))

        return statuses


    @classmethod
    def __get_instagram_statuses(cls, url: str) -> Dict:
        statuses = {}

        # ToDo: error handling
        response = requests.get(url)

        soup = BeautifulSoup(response.content, 'lxml')
        js = soup.find("script", text=re.compile("window._sharedData")).text
        data = json.loads(js[js.find("{"):js.rfind("}")+1]);

        statuses['following_count'] = data['entry_data']['ProfilePage'][0]['graphql']['user']['edge_follow']['count']
        statuses['follower_count'] = data['entry_data']['ProfilePage'][0]['graphql']['user']['edge_followed_by']['count']

        return statuses


    @staticmethod
    def __get_element_by_class(soup: BeautifulSoup, class_name: str) -> BeautifulSoup:
        return soup.find(attrs={'class': re.compile('^' + class_name + '$')})


social_medias = SocialMedias()
print(social_medias.get_statuses())
実行結果
$ python social_medias.py
{'instagram': {'follower_count': 17, 'following_count': 10}, 'twitter': {'follower_count': 763, 'following_count': 615}}

参考させていただきました

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.