Python3
Jupyter

Instagramから世界中の人々の行動を探るぜ

本編はこちら中国広州市にあるリトルアフリカ、そこにやってくる彼らは実際どこからやってくるのかデータを集めて検証した

本編サマリ: 中国の広州にはアフリカやアラブ系の人が買い付けに来るリトルアフリカがあるらしいと本で読んだので実際に行ってきた。なるほど現地には黒人やアラブ人がたくさんいた。ところが本によるとタンザニアの人が多いと言う話だったが、正直誰がタンザニア人かどうかなんて区別がつかなかった。そこでリトルアフリカにタグ付けしてInstagramに写真を上げている人を追跡して統計データをとったところタンザニア人が多いということを確認した。(オレは一体何をしているんだ)

Qiitaのこの記事ではInstagramのスクレイピング方法を紹介する。

すげぇ雑に結果をプロットしたのはこんなの詳しくは本編へ
スクリーンショット 2018-12-14 13.58.50.png
https://datastudio.google.com/embed/reporting/1RdZUJZ6MIXuPh6-hIqzknKyNVsfSsLr1/page/R60Y

スクリーンショット 2018-12-14 13.59.49.png
https://www.google.com/maps/d/embed?mid=1cm6NFsdHSo0M_r8U_mdzi_9Pjpu35s5f

こっから先は技術編

InstagramのAPIは2018年の4月あたりで他の人のデータを取得できなくなってしまった。そこでInstagramの多分Web版スクレイピングするライブラリがPythonであったの利用してみることにした

instagram-scraperでインスタグラムをスクレイピング

instagram-scraperの画像をスクレイピングしてくれるライブラリ

pipでインストールできる

pip install instagram-scraper
instagram-scraper TARGET_USER_NAME -u USER_NAME -p PASSWORD  

TARGET_USER_NAME: スクレイピングしたいユーザのユーザ名
USER_NAME 自分のインスタグラムのユーザ名
PASSWORD: 自分のインスタグラムのパスワード

パラメータはこんな感じのものがあり

最大DL枚数
--maximum

DLするファイル選択
-t or --media-types
none #DLしないでメタデータだけ取得できる
image #画像データだけ欲しい時(ビデオは含まない)

メタデータが欲しい時
--media-metadata

メタデータに場所データを付ける
--include-location

locationIDで場所指定
--location

これでTARGET_USER_NAMEの画像をDLしないでJSON形式のメタデータを含んで取得できる

instagram-scraper TARGET_USER_NAME -u USER_NAME -p PASSWORD --maximum 150 --media-metadata --include-location -t none

これで取得できたデータのうち、位置情報は下記のように形式で取得できる。
ただし、対象の国にちゃんと住所があるかのほうが問題?ジンバブエとか変なデータが多い

        "location": {
            "address_json": "{\"street_address\": \"\", \"zip_code\": \"\", \"city_name\": \"Aberdeen, Hong Kong\", \"region_name\": \"\", \"country_code\": \"HK\"}",
            "has_public_page": true,
            "id": "234884489",
            "name": "Aberdeen, Hong Kong",
            "slug": "aberdeen-hong-kong"
        },

instagram-scraperでの取得の仕方がわかった次は、ある特定の場所で投稿しているデータを集める

InstagramのlocationIDをしらべる

InstagramのWeb版で場所を検索して表示したURLは下記のように形式をしている

小米駅のURL: https://www.instagram.com/explore/locations/346112693/xiaobei-station/

このURLのlocationsの後ろの346112693がlocationID

locationIDを元に小米駅のデータをinstagram-scraperを使って下記コマンドで取得する

instagram-scraper --location 346112693  -u USER_NAME -p PASSWORD --maximum 1000 --media-metadata --include-location -t none

小米取得したJSONデータからショートコードを取得する

先のコマンドで取得したデータではユーザ名がわからないが、そのかわりshortcodeを取得することはできる

ショートコードを元にした1画像の詳細データ

jsonデータから、shortcodeを取得したらあるユーザの画像データを取得することができる。
https://www.instagram.com/p/BnxfaxpHcnP/?__a=1

instagram-scraperで取得した小米駅のメタデータのJSONをパースして、shortcodeを抜き出し、shortcodeを元に詳細データを取得して
画像をアップロードしたユーザ名のリストをテキスト取得(username_list.txt)

ユーザ名のリストをゲットしたので、そのユーザ名の画像のメタデータからlocation付きで取得していく

ユーザ名のリストを元に再びinstagram-scraper各ユーザごと最新151枚ずつ分のメタデータを取得していく

instagram-scraper -f username_list.txt -u USER_NAME -p PASSWORD --media-metadata --include-location -d images -t none --maximum 200

余談:maximumを100にすると何故か51枚の画像で終わる。maximumを200にすると何故か151枚の画像で終わる 多分1ページめの画像が50でプロフィール画像が1枚の仕様のせいだと思われる。

各ユーザのアップした画像のJSONデータを元にTSVを作成する

Googleスプレッドシートで加工しやすいように、下記のように各ユーザのJSONデータをパースしてTSVに変換した

  • 画像のインスタグラムURL ショートコードプラスURLを結合したもの
  • 画像の直のURL
  • username
  • user_id: 
  • 国コード 2レターコード USとかJPとか
  • 住所: locationデータをいい感じに結合する
  • 日付: UNIXタイム

スプレッドシートに貼り付けたデータはこんな感じ

user_id username url image_url timestamp country_code address
370335720 kinsalakeren_ https://www.instagram.com/p/Bn6RXCPhQao/ https://scontent-nrt1-1.cdninstagram.com/vp/a91a0df37dc829aebef2f5d5faa2bff7/5C2CF792/t51.2885-15/e35/41532985_313224696123029_809961737153344657_n.jpg?se=7&ig_cache_key=MTg3MTg4NDY4MDIxMTc4MjYzOA%3D%3D.2 1537366096 CD Kinshasa, Congo, Kinshasa, Congo, CD
370335720 kinsalakeren_ https://www.instagram.com/p/BnwxobNn1yv/ https://scontent-nrt1-1.cdninstagram.com/vp/55046d7190806342262417fcf5fcaab8/5C1F654B/t51.2885-15/e35/40325334_238065576867555_2115481471343003588_n.jpg?se=7&ig_cache_key=MTg2OTIxMTI2MDc2NDQ2NjIzNw%3D%3D.2 1537047471 CD A Casa Mia, 70b avenue Uvira , Gombe ( prêt du Grand Hotel), Kinshasa, Congo, CD
370335720 kinsalakeren_ https://www.instagram.com/p/BmrBh5xnRwO/ https://scontent-nrt1-1.cdninstagram.com/vp/bc6e1077994451a2884030cf1f768d5e/5C264B0B/t51.2885-15/e35/38666441_268654153965273_8479752776593702912_n.jpg?se=7&ig_cache_key=MTg0OTU3ODc5OTc5MDYyNzg1NA%3D%3D.2 1534706996 KE Nairobi, Kenya, Nairobi, Kenya, KE
370335720 kinsalakeren_ https://www.instagram.com/p/BlQZnAGn2me/ https://scontent-nrt1-1.cdninstagram.com/vp/51f0e97f1a5d043aeb282cee1c93d35e/5C3C24A6/t51.2885-15/e35/36513964_655662088139029_3126250147218980864_n.jpg?se=7&ig_cache_key=MTgyNDA3MDQ4MDQxODUzMTc0Mg%3D%3D.2 1531666167 CD A Casa Mia, 70b avenue Uvira , Gombe ( prêt du Grand Hotel), Kinshasa, Congo, CD
370335720 kinsalakeren_ https://www.instagram.com/p/BjhVHuqg0R2/ https://scontent-nrt1-1.cdninstagram.com/vp/d8205a4f842275cdb99e1a3d9339d140/5C5DB888/t51.2885-15/e35/35998494_206610886724304_6171552612018552832_n.jpg?se=7&ig_cache_key=MTc5MjgwNzAxNjc4ODYwODExOA%3D%3D.2 1527939272 KE Sankara Nairobi, Woodvale Grove,Westlands, Nairobi, Kenya, KE

TSVまで作ったらあとはGoogle Colabで読み込ませてPandasでゴニョゴニョやれば良い
詳細は下記のリンクから
中国広州市にあるリトルアフリカ、そこにやってくる彼らは実際どこからやってくるのかデータを集めて検証した