LoginSignup
33
34

More than 3 years have passed since last update.

AWS Lambdaで動的サイトのwebスクレイピングをしてtwitterに投稿するbotを作った

Last updated at Posted at 2018-10-29

はじめに

webページからスクレイピングをしたデータを簡単に加工して自動投稿するtwitterのbotを作りました。
完全に初見のLambdaとPythonでできました。
以下のサイトを組み合わせただけのほぼパクリ記事です。作業ログです。
【Python】Chrome headlessで動的サイトのスクレイピング on AWS Lambda
AWS Lambda から Twitter に投稿する

無駄に面倒なAPI Keyとアクセストークンの入手の方法についてですが、以下の記事を参考にしてください。
登録ページ:https://apps.twitter.com/
https://qiita.com/tdkn/items/521686c240b0c5bc6207
https://syncer.jp/Web/API/Twitter/REST_API/

追記(2019/12/23)

Python3系で実行し、容量を食うchroniumをLambda Layerに設定することでコンソールからも関数を確認できるようにして、
なおかつ、デプロイはServerless Frameworkでできるように改良しました。

AWS Lambdaで動的サイトのwebスクレイピングをしてtwitterに投稿するbotを作った(続)

環境

Cloud9
Python 2.7.10(3系でもいけるはずです)
Twitter developに登録してAPI Keyとアクセストークンを入手済み
AWSのアカウント

ディレクトリ作成

requests_oauthlibをpip installしたときの挙動がMacとAmazon Linuxでは違ったので以下パッケージのインストールはCloud9上で全て行います。
ということでまずはCloud9で適当に環境を作成します。
そして作業ディレクトリを作成します。

$ mkdir webscraping_tweetbot
$ cd webscraping_tweetbot

seleniumインストール

作成したディレクトリにseleniumをインストールします。
pipでインストールするのですが、コマンドを実行したOS用のseleniumが自動でインストールされます。
今回は最終的にLambdaでプログラムを実行してもらうのでAmazon Linux用のseleniumが必要です。
参考記事に従ってバージョンも同じものをダウンロードします。

$ pip install selenium==3.13.0 -t .

後は作成されたディレクトリごとダウンロードして先ほどの作業ディレクトリの中に置きます。

requests_oauthlibのインストール

作業ディレクトリwebscraping_tweetbot直下に認証ライブラリであるrequests_oauthlibをインストールします。twitterに接続する際に必要になります。

$ pip install requests_oauthlib -t ./

beautifulsoup4のインストール

htmlを入手した後、データを整形するのにbeautifulsoupを使うので、webscraping_tweetbot直下にインストールします。

$ pip install beautifulsoup4 -t ./

serverless-chromiumのダウンロード

binディレクトリを作成してそこにダウンロードします。

最新版はPythonで動かない(2018年4月27日現在 [参照])ため、v.0.0-37を入れます。

引用: https://qiita.com/nabehide/items/754eb7b7e9fff9a1047d

$ mkdir bin
$ curl -SL https://github.com/adieuadieu/serverless-chrome/releases/download/v1.0.0-37/stable-headless-chromium-amazonlinux-2017-03.zip > headless-chromium.zip
$ unzip headless-chromium.zip -d bin/
$ rm headless-chromium.zip

Chrome driver のダウンロード

serverless-chromiumと同様です。

$ curl -SL https://chromedriver.storage.googleapis.com/2.37/chromedriver_linux64.zip > chromedriver.zip
$ unzip chromedriver.zip -d bin/
$ rm chromedriver.zip

これでライブラリのインストールは終わりです。

lambda_function.pyの作成

lambdaにtweetを投稿するlambda_function.pyを作成します。
webスクレイピングそのものはwebscrape.pyのwebscrapeという関数にさせます。
beautifulsoupを使ったwebスクレイピングについてはこちらを参考
アクセストークンなどはLambdaの環境変数として設定します。

lambda_function.py
#coding:utf-8

from requests_oauthlib import OAuth1Session
from webscrape import webscrape
import urllib3
import os

CK = os.environ['CK']
CS = os.environ['CS']
AT = os.environ['AT']
AS = os.environ['AS']

URL = 'https://api.twitter.com/1.1/statuses/update.json'

def lambda_handler(event, context):
    # webscrape.pyのwebscrapeの返り値(shapingdata(html))を受け取る。
    tweet=webscrape()

    session = OAuth1Session(CK, CS, AT, AS)

    params = {"status": tweet }
    twitter = OAuth1Session(CK, CS, AT, AS)
    req = twitter.post(URL, params = params)

    if req.status_code == 200:
        return tweet
    else:
        return req.status_code

webscrape.pyの作成

webscrape.py

#coding:utf-8

from selenium import webdriver
from bs4 import BeautifulSoup
import time

def webscrape():
    # webdriver settings
    options = webdriver.ChromeOptions()
    options.binary_location = "./bin/headless-chromium"
    options.add_argument("--headless")
    options.add_argument("--no-sandbox")
    options.add_argument("--single-process")

    driver = webdriver.Chrome(
        executable_path="./bin/chromedriver",
        chrome_options=options
    )

    # web scraping
    driver.get("URL")
    #ここの時間が長いとlambdaの料金が無駄にかかります。driverがページの表示にかかる時間分だけを設定するのが良いです。
    time.sleep(0.3) 
    html = driver.page_source.encode('utf-8')

    return shaping_data(html)

def shaping_data(html):

    soup = BeautifulSoup(html, "html.parser")
    # 中略(beautifusoupの使い方に関しては他の記事を参照してください。)
    return tweet_data

Zip化

webscraping_tweetbot上でLambdaにアップロードするファイルをzip化します。
あとはこれをダウンロードします。

zip -r webscraping_tweetbot.zip ./

Lambdaで関数作成

Lambdaの関数を作成します。
twitterのbotを作るのでcloudwatch eventへのアクセス許可のIAMロールを割り当ててます。
ない場合は作りましょう。

スクリーンショット 2018-10-29 12.08.19.png

lambdaにzipをアップロードしてデプロイ

作成したzipファイルをアップロードします。10MB以上ですがアップロードはできます。
S3に一度アップロードしてからアップロードをすることもできます。AWSはこちらの方法を推奨のようです。この場合はアップロードさえ終わればS3から消しても大丈夫です。
ハンドラのところは
Lambdaで動かすPythonファイルへのパス.そのファイル内で実行する関数の名前
を入力します。(今回はlambda_function.lambda_handler)

スクリーンショット 2018-10-29 12.11.37.png

さらに画面下で環境変数を設定する項目があるのでそこでアクセストークンなどを(CK,CS,AK,AS)を忘れず設定しましょう。(参考)

保存をしてテストを動かして無事グリーンになること確認したら、twitterにちゃんと投稿されているか確認します。

Cloudwatch Eventsのルール適用

左側のリストからCloudWatch Eventsを選択します。

スクリーンショット 2018-10-29 12.17.40.png

すると下に設定画面が出てくるのでcron式またはrate式で投稿するスケジュールを設定します。

スクリーンショット 2018-10-29 12.24.26.png

後は追加して、設定したスケジュールで投稿されたら終了です!お疲れ様でした。

作ったもの

ソースコードはこちら
https://github.com/kihoair/intro_bot/
まだ昨日(2018/10/28)からしか動いていないのですが、制作物です。
https://twitter.com/intro_tweetbot
個人的によく行くジャズバーのジャムセッションのスケジュールを1日1回自動でつぶやいています。メンバー見てからセッションに行きたくなったりすることってあるんですよね。それでは!

33
34
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
33
34