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

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

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

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

#ニュースサイトの見出しをスクレイピング
まずは対象となるサイトから求めている情報を取得するコードを作成します。
この章は【[PythonでWebスクレイピングをしよう（天気予報）](https://qiita.com/neet-AI/items/d434f3a96223c12fbdd3)】を参考にしています。
###インストールするモジュール
requests：webページから何かをダウンロードしたいときに使用するモジュール
BeautifulSoup：取得したWebページから情報を抽出するモジュール
###コード
```python: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に投稿する](https://qiita.com/shtnkgm/items/4f0e4dcbb9eb52fdf316)】を参考にしています。

```python: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に投稿する](https://qiita.com/shtnkgm/items/4f0e4dcbb9eb52fdf316)】を参考にしてください。

「そもそもWebhook とはなんぞ？」という方は、【[Webhookとは？](https://qiita.com/soarflat/items/ed970f6dc59b2ab76169)】をご覧ください。

###進捗確認
現在のコードはこんな感じ。

```python: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ファンクションを定期的に実行する](https://qiita.com/Toshinori_Hayashi/items/5b0a72dc64ced91717c0)
b[【AWS】Lambdaでpipしたいと思ったときにすべきこと](https://qiita.com/Hironsan/items/0eb5578f3321c72637b4)
###そもそもlambdaとは
awsのサービスの一つです。
特定のイベントが生じた際に、アップロードしておいたコードを自動で実行してくれます。
詳しくは[こちら](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/welcome.html)。
###トリガーの設定
a（[【AWS】lambdaファンクションを定期的に実行する](https://qiita.com/Toshinori_Hayashi/items/5b0a72dc64ced91717c0)）の「定期実行の設定」以降を参考にして行いましょう。
今回はルールタイプをスケジュール式にしました。
毎朝6時に実行させたかったので、【cron(0 21 * * ? *)】と入力しました。書き方の詳細は[こちら](https://www.suzu6.net/posts/136-lambda-cron-rate/)。
###コードの実装
b（[【AWS】Lambdaでpipしたいと思ったときにすべきこと](https://qiita.com/Hironsan/items/0eb5578f3321c72637b4)）を参考に行いましょう。
この記事の手順を経ないと、外部モジュールをimportすることができません。
＊zipファイルの作成は普通にGUIでやりました。

###進捗確認・注意点
現在のコードやディレクトリの状態はこんな感じ。
![lambda_1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469705/c1fceea2-d788-bbbd-9cdc-249181bc99bf.png)
実は、 scraping_jr 関数を定義している部分に event と context という引数を新たに指定しています。
理由はわかりませんが、「引数が2個ないといけないのに0個しかないよ！」とのエラーがでたので、資料bの真似をしました。

テストも成功。翌朝の起床時には狙い通り「日経×TECH」のトップニュースがに届いていました。
これでめでたく完成です。
#（蛇足）システムを定期的に実行するために・・・
毎朝システムを実行するためにいちいちわざわざPCを起動させるのは面倒なので今回はlambdaにコードを載せました。
最初はGoogleDriveのColabを使ってスマホと連携できないかと思って少し調べてみましたが、なんだかよくわからなかったので諦めました。
#まとめ
今回はpythonとAWSLambdaを用いて定時にwebスクレイピングを行い、内容をSlackに転送するシステムを作成しました。
もっと効率的なコードの書き方やツールがありましたら、ご教示ください。

#参考資料
・[【保存版・初心者向け】Python 目的別チュートリアル](https://qiita.com/tani_AI_Academy/items/3edc5effeb386ae3caa9)
・[PythonでWebスクレイピングをしよう（天気予報）](https://qiita.com/neet-AI/items/d434f3a96223c12fbdd3)
・[Python3でslackに投稿する](https://qiita.com/shtnkgm/items/4f0e4dcbb9eb52fdf316)
・[Webhookとは？](https://qiita.com/soarflat/items/ed970f6dc59b2ab76169)
・[【AWS】lambdaファンクションを定期的に実行する](https://qiita.com/Toshinori_Hayashi/items/5b0a72dc64ced91717c0)
・[【AWS】Lambdaでpipしたいと思ったときにすべきこと](https://qiita.com/Hironsan/items/0eb5578f3321c72637b4)
・[AWS Lambda とは](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/welcome.html)
・[AWS Lambdaで定期処理を実行するためのRateとCronの設定](https://www.suzu6.net/posts/136-lambda-cron-rate/)