8
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Pythonで、位置情報から花粉情報を送るLINEBotを作った。

Last updated at Posted at 2020-03-25

#(1)背景
・いつもこの時期から花粉に悩まされる。
・今年はコロナもあって花粉症者は辛い。
・マスク不足。
・pythonとscraping、herokuを使って何か作ってみたい。
・アウトプットイメージ ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
unnamed.png

#(2)環境構築
デスクトップに、ディレクトリline_kafunを作成。
line-sdkを扱うmain.pyと、Yahoo天気情報から花粉情報を収集するweather.pyを作成。

ディレクトリ構成は以下の通り。

line_kafun
├main.py
├weather.py
├Procfile
├runtime.txt
└requirements.txt

必要なパッケージをインストール。

pip install flask
pip install line-bot-sdk
pip install beautifulsopu4
pip install gunicorn
pip install lxml
pip install requests

#(3)main.py

main.py
from flask import Flask, request, abort
from linebot import (
    LineBotApi, WebhookHandler
)
from linebot.exceptions import (
    InvalidSignatureError
)
from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage,LocationMessage
)
import os
import weather as wt #weather.pyをインポート


app = Flask(__name__)

#Herokuの環境変数設定
YOUR_CHANNEL_ACCESS_TOKEN = os.environ["YOUR_CHANNEL_ACCESS_TOKEN"]
YOUR_CHANNEL_SECRET = os.environ["YOUR_CHANNEL_SECRET"]

line_bot_api = LineBotApi(YOUR_CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(YOUR_CHANNEL_SECRET)

@app.route("/")
def hello_world():
    return "hello world!"


@app.route("/callback", methods=['POST'])
def callback():
    signature = request.headers['X-Line-Signature']
    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)

    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        abort(400)
    return 'OK'



@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    if '花粉' in event.message.text:
        line_bot_api.reply_message(
            event.reply_token,
       [
            TextSendMessage(text='現在の位置情報は?'),
            TextSendMessage(text='https://line.me/R/nv/location/'),
            ]
        )
  

@handler.add(MessageEvent, message=LocationMessage)
def handle_location(event):
    text = event.message.address
    result = wt.get_weather(text)
    line_bot_api.reply_message(
    event.reply_token,
    TextSendMessage(text=result + '\uDBC0\uDC20')
    )


if __name__ == "__main__":
    port = int(os.getenv("PORT", 5000))
    app.run(host="0.0.0.0", port=port)

###補足説明
・text = event.message.addressの箇所のaddressは、linedevelopersのapiリファレンスを参考にした。スクリーンショット 2020-03-25 22.51.02.png
・ TextSendMessageの箇所はLINEapiリファレンスのURLスキームを参考にした。
スクリーンショット 2020-03-25 23.03.19.png
なお、URLスキームは1対1のトークのみで利用可能であり、グループでの利用は不可。
・'\uDBC0\uDC20'は絵文字で、LINE BOTで「LINEの絵文字」を使うを参考にした。

#(4)weather.py
Yhaooから花粉情報をスクレイピング。

weather.py
import requests
from bs4 import BeautifulSoup
import re
import lxml


def get_weather(text):
    location = re.findall('\d{3}-\d{4}',text)
    location2 = location[0].replace('-','')
    url1 = "https://weather.yahoo.co.jp/weather/search/?p={}".format(location2)
    url2 = ""

    #1つ目のurlからhtmlの情報を取得し、そこから2つ目のurlを取得
    res = requests.get(url1)
    res.encoding = res.apparent_encoding
    html_doc = res.text
    soup = BeautifulSoup(html_doc,"lxml")
    content_1 = soup.find_all(id = 'rsltmuni')
    for i in content_1:
        content_2 = i.find('a')
        url2 = 'https:' + content_2.get('href')


    #2つ目のurlから今日と明日の日付を取得(today、nextday)
    res = requests.get(url2)
    res.encoding = res.apparent_encoding
    html_doc = res.text
    soup = BeautifulSoup(html_doc,"lxml")
    content_3 = soup.find_all('p',class_='date')
    today = content_3[0].get_text()
    nextday = content_3[1].get_text()

    #今日と明日の花粉状況を取得
    content_4 = soup.find_all('p',class_='flying')
    today_kafun = content_4[0].get_text()
    nextday_kafun = content_4[1].get_text()

    #エリアを取得
    content_5 = soup.find_all('h2',class_='yjM')
    area = content_5[0].get_text()


    result = today + 'の' + area + 'は' + '「{}」'.format(today_kafun) + 'だよ。' + '\n' +'\n'+ nextday + 'の' + area + 'は' + '「{}」'.format(nextday_kafun) + 'だよ。' + '\n' +'\n' + '気をつけてね。'

    return result

#(5)Herokuへデプロイと、LINE DevelopersのWebhook設定
最後に必要なファイル(requirements.txt、Procfile、runtime.txt)を作成し、Herokuへデプロイする。デプロイ方法は多くのサイトで紹介しているので割愛。詳細はHeroku、Flask、SQLAlchemyで掲示板を作るを参考。
また、LINE DevelopersのWebhook設定もこれも多くのサイトで紹介しているので割愛。詳細はLINE BOT(オウム返し)を作るを参考。

###出来上がった、LINEBotに、”花粉”と入力すると位置情報を聞いてくるので、タップすると、花粉情報を取得できる(完成)。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?