LoginSignup
19
22

More than 5 years have passed since last update.

簡単に出来るサーバレスでのInstagramのスクレイピング

Last updated at Posted at 2017-09-15

最初に

今回はinstagramのユーザ名を指定すると最新のフィードを取得出来るAPIを作っていきます。
私自身、初めて利用するものばかりだったため、誰でもコピペと設定で簡単に出来るよう書いたつもりです。
勉強用サンプルとしてInstagramを使っただけなので、日常的にスクレイピングするのは控えましょう。

各種ツールやサービス

・AWS
EC2(Amazon linux)
API Gateway
AWS Lambda

・各種バージョン
python3.6.2
phantomjs-2.1.1

環境設定(Python編)

Amazon linux上にPython3の環境を作ります。Vagrantでも問題無いです。
Lambdaのランタイムに合わせて3.6系を選択しています。
この辺りは様々なサイトで解説されているので、わからない場合はそちらを参照してください。

$ sudo yum install gcc zlib-devel bzip2 bzip2-devel readline readline-devel sqlite sqlite-devel openssl openssl-devel git
$ git clone https://github.com/yyuu/pyenv.git ~/.pyenv

$ pyenv --version
pyenv 1.1.3-33-g48aa0c4

$ pyenv install --list
$ pyenv install 3.6.2
$ pyenv versions
* system (set by /home/ec2-user/.pyenv/version)
  3.6.2

$ pyenv global 3.6.2
$ pyenv rehash
$ python --version
Python 3.6.2

$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
$ source ~/.bash_profile

環境設定(準備編)

Lambdaのローカル開発環境や今回利用するモジュールを準備します。
今回はworkspaceディレクトリで作業を行っています。
Lambadにアップする際にはzipにするため、必ず作業ディレクトリ下で行って下さい。

$ mkdir workspace
$ cd workspace/

### Lambdaのローカル開発モジュール
$ pip install python-lambda-local

### zipに含めるためにモジュールをカレントディレクトリにインストール
$ pip install requests -t .
$ pip install html5lib -t .
$ pip install bs4 -t .

### Lambdaのeventに渡す値を設定。
### 今回は日本で一番人気のある方のアカウントを対象にします。
$ vi event.json
{
  "account": "watanabenaomi703"
}


スクレイピング用プログラム

単純にInstagramのプロフィールページで「window._sharedData」変数にセットしているJSONを取得してフィードの部分だけ取得してきています。

lambda_function.py
# -*- coding: utf-8 -*-
import json
import requests
import re
from bs4 import BeautifulSoup

def lambda_handler(event, context):
    url = 'https://www.instagram.com/{}/'.format(event['account'])
    res = requests.get(url)
    soup = BeautifulSoup(res.content, 'html5lib')
    js = soup.find("script",text=re.compile("window._sharedData")).text
    data = js[js.find("{"):js.rfind("}")+1];
    return json.loads(data)['entry_data']['ProfilePage'][0]['user']['media']['nodes']

テスト実施

このコマンドでテストを実施します。
実施してJSONデータが返ってきたら成功です。

$ python-lambda-local -f lambda_handler lambda_function.py event.json

テストが成功したら下記コマンドで圧縮します。
なぜか違うディレクトリで圧縮すると上手く動かなかったため注意して下さい。

$ zip -r ../workspace .

Lambda設定

AWS Lambdaの画面にアクセスし、右上の「関数の作成」を行います。

スクリーンショット 2017-09-15 15.02.45.png

設計図はいろいろありますが、今回は右上の「一から作成」を行います。

スクリーンショット 2017-09-15 15.02.59.png

トリガーは設定せず「次へ」を押します。
スクリーンショット 2017-09-15 15.03.13.png

今回は名前を「instagram-scraping」とし、ランタイムはPython3.6にします。
ハンドラは「ファイル名.関数名」です。
デフォルトは「index.handler」となっていますが、「lambda_function.lambda_handler」に直しましょう。

スクリーンショット 2017-09-15 15.06.56.png

ZIPファイルをアップロードします。
スクリーンショット 2017-09-15 17.09.41.png

タイムアウトを少し長くしましょう。
スクリーンショット 2017-09-15 15.07.56.png

アップロードが終わったらこのような画面になります。
スクリーンショット 2017-09-15 15.11.59.png

テストを実行して成功するとこのように表示されます。
これでLambdaの準備は終わりです。
スクリーンショット 2017-09-15 17.12.05.png

API Gateway設定

API Gatewayの画面に行き、新しいAPIを作成します。
名前は「instagram-scraping」で作成します。
スクリーンショット 2017-09-15 16.17.06.png

上の「アクション」プルダウンからリソース(APIのpath)を作成してGETで受け付けるようにします。
今回は「/」でも問題ないですが、「instagram-scraping」で作っています。

スクリーンショット 2017-09-15 16.19.27.png

GETパラメータをLambdaに渡す準備をします。
作成したリソースの「統合リクエスト」を選択します。
スクリーンショット 2017-09-15 17.16.34.png

一番下の本文マッピングテンプレートを画像のように設定します。

{
  "account": "$input.params('account')"
}

スクリーンショット 2017-09-15 16.40.28.png

API Gatewayはデプロイしないとアクセスできないため、「アクション」プルダウンからデプロイを実施してください。
ステージ名はURLに含まれるため、公開しても問題ないよう「v1」とかでいいと思います。
これで準備完了です。

APIにアクセス

こんな感じのURLが出来上がるので、ブラウザでもcurlでもいいのでアクセスしてみましょう。
JSONデータが返ってきたら完成です。
https://{固有の値}.execute-api.ap-northeast-1.amazonaws.com/{ステージ名}/instagram-scraping?account=watanabenaomi703

最後に

簡単にサーバレスでAPIが作成できましたが、ある程度規模が大きくなるとLambdaのコードの管理やAPIのリソース管理が煩雑になりそうですし、諸々面倒な部分は多いですが、他機能と絡まない独立しているAPIを作る場合は非常に便利なので、もし要件に合う場合は検討してもいいのではないかと感じました。

参考URL

19
22
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
22