LoginSignup
6
6

More than 3 years have passed since last update.

AWSLambdaを用いて定時にpythonスクレイピングコードを実行する

Posted at

はじめに

pythonを学び始めて少し時間が経ち、なんだかそれっぽいものを作ってみたくなりました。
そこで、【保存版・初心者向け】Python 目的別チュートリアルを読んでみて、初心者向けのwebスクレイピングを行うコードを書いてみることにしました。

目標完成物

毎朝「日経×TECH」からトップニュースとトップページURLをSlackに投稿する。

環境

python3.7.2
Windows10

手順

1. ニュースサイトの見出しをスクレイピング
2. Slackに転送
3. AWSLambdaに載せて毎朝6時に実行するよう設定

ニュースサイトの見出しをスクレイピング

まずは対象となるサイトから求めている情報を取得するコードを作成します。
この章は【PythonでWebスクレイピングをしよう(天気予報)】を参考にしています。

インストールするモジュール

requests:webページから何かをダウンロードしたいときに使用するモジュール
BeautifulSoup:取得したWebページから情報を抽出するモジュール

コード

nikkei_IT.py
#まだpip install していなかったらやっておきましょう。
import requests
from bs4 import BeautifulSoup

def scraping_jr():
    #スクレイピングしたいwebページのURL
    TARGET_URL = "https://tech.nikkeibp.co.jp/news/index_it.html"

    res = requests.get(TARGET_URL)
    soup = BeautifulSoup(res.text, 'lxml')

    #取得したい箇所のhtmlタグを選択
    container = soup.find("article").find('div',{'class':'articleList'})
    info_elements = container.find("ul",{'class':'top_panel_B'}).select('li')

    links = []

    for info_element in info_elements:
        links[len(links):len(links)] = info_element.find("div",{'class':'text'}).find('a')

注意

findメソッドは引数として指定したタグの要素を一つだけ持ちます。
対してselectメソッドは指定したタグの要素をすべてリストとして持ちます。

今回はトップニュースのみを取得したかったので、該当部分のみをfindで選択し、その選択領域内のニュースすべて(「li」タグ)をselectメソッドを用いて取得しました。

あとはliタグ内のニュース見出しを抽出すれば完成です。
新たに作成したlinksリストに格納していきます。

Slack転送

取得した内容を自分のSlackに転送します。
この章の内容は、【Python3でslackに投稿する】を参考にしています。

nikkei_IT.py
#slackwebモジュールもpip install しておきましょう。
import requests, slackweb
from bs4 import BeautifulSoup

SLACK_WEB_URL = "(WebhookのURL)"

    #中略

slack = slackweb.Slack(SLACK_WEB_URL)

    for link in links:
       l = [link, TARGET_URL]
       message = "\n".join(l)

       slack.notify(text=message, unfurl_links = 'true')

Incoming Webhook の設定をする必要があります。方法は【Python3でslackに投稿する】を参考にしてください。

「そもそもWebhook とはなんぞ?」という方は、【Webhookとは?】をご覧ください。

進捗確認

現在のコードはこんな感じ。

nikkei_IT.py
import requests, slackweb
from bs4 import BeautifulSoup

def scraping_jr():
    TARGET_URL = "https://tech.nikkeibp.co.jp/news/index_it.html"
    SLACK_WEB_URL = "(WebhookのURL)"

    res = requests.get(TARGET_URL)
    soup = BeautifulSoup(res.text, 'lxml')

    container = soup.find("article").find('div',{'class':'articleList'})
    info_elements = container.find("ul",{'class':'top_panel_B'}).select('li')

    links = []

    for info_element in info_elements:
        links[len(links):len(links)] = info_element.find("div",{'class':'text'}).find('a')

    slack = slackweb.Slack(SLACK_WEB_URL)

    for link in links:
       l = [link, TARGET_URL]
       message = "\n".join(l)

       slack.notify(text=message, unfurl_links = 'true')

scraping_jr()

とりあえずこれで、実行すれば求めていた動きはしてくれます。

AWSLambdaに載せる

ではこのコードをlambdaに載せて、定期的に自動で実行させましょう。
この章は以下の記事を参考にしています。
a【AWS】lambdaファンクションを定期的に実行する
b【AWS】Lambdaでpipしたいと思ったときにすべきこと

そもそもlambdaとは

awsのサービスの一つです。
特定のイベントが生じた際に、アップロードしておいたコードを自動で実行してくれます。
詳しくはこちら

トリガーの設定

a(【AWS】lambdaファンクションを定期的に実行する)の「定期実行の設定」以降を参考にして行いましょう。
今回はルールタイプをスケジュール式にしました。
毎朝6時に実行させたかったので、【cron(0 21 * * ? *)】と入力しました。書き方の詳細はこちら

コードの実装

b(【AWS】Lambdaでpipしたいと思ったときにすべきこと)を参考に行いましょう。
この記事の手順を経ないと、外部モジュールをimportすることができません。
*zipファイルの作成は普通にGUIでやりました。

進捗確認・注意点

現在のコードやディレクトリの状態はこんな感じ。
lambda_1.PNG
実は、 scraping_jr 関数を定義している部分に event と context という引数を新たに指定しています。
理由はわかりませんが、「引数が2個ないといけないのに0個しかないよ!」とのエラーがでたので、資料bの真似をしました。

テストも成功。翌朝の起床時には狙い通り「日経×TECH」のトップニュースがに届いていました。
これでめでたく完成です。

(蛇足)システムを定期的に実行するために・・・

毎朝システムを実行するためにいちいちわざわざPCを起動させるのは面倒なので今回はlambdaにコードを載せました。
最初はGoogleDriveのColabを使ってスマホと連携できないかと思って少し調べてみましたが、なんだかよくわからなかったので諦めました。

まとめ

今回はpythonとAWSLambdaを用いて定時にwebスクレイピングを行い、内容をSlackに転送するシステムを作成しました。
もっと効率的なコードの書き方やツールがありましたら、ご教示ください。

参考資料

【保存版・初心者向け】Python 目的別チュートリアル
PythonでWebスクレイピングをしよう(天気予報)
Python3でslackに投稿する
Webhookとは?
【AWS】lambdaファンクションを定期的に実行する
【AWS】Lambdaでpipしたいと思ったときにすべきこと
AWS Lambda とは
AWS Lambdaで定期処理を実行するためのRateとCronの設定

6
6
1

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
6
6