도내의 코로나 감염자수를 지정 시각에 보고해 주는 Discord의 Bot를 Docker상에서 작성해 보았다

2020년의 신졸로 IT계에 근무하고 있습니다. Qiita에서의 첫 투고이므로 이르지 않는 점도 있다고 생각합니다만 잘 부탁드립니다.

목적



discordApi를 이용한 bot 만들기에는 빠졌기 때문에, 스크래핑의 연습도 과연 타이틀과 같은 bot를 작성해 보았다.

실행 환경



Windows


  • windows10
  • Python3.7.3

  • VPS


  • CentOS 7

  • 절차



    Windows에서 빌드하고 bot의 동작을 확인합니다.



    bot의 토큰 취득 등은 다른 기사에서 많이 쓰여 있으므로 생략합니다. 다음 명령과 함께 사용할 라이브러리 설치pip install beautifulsoup4pip install requestspip install discord이번 스크래핑의 대상으로 하는 사이트는 도쿄도의 신형 코로나 바이러스 감염증 대책 사이트 입니다.
    먼저 BeautifulSoup에서 원하는 데이터를 얻을 수 있는지 확인해 보겠습니다. 소스 코드는 다음과 같다.

    soup.py
    
    import requests
    from bs4 import BeautifulSoup
    
    #getでURLに接続しデータを取得
    res= requests.get("https://stopcovid19.metro.tokyo.lg.jp/cards/number-of-confirmed-cases/")
    
    #オブジェクトを格納
    soup = BeautifulSoup(res.text,"html.parser")
    
    #ほしい部分のタグおよびクラスでフィルターをかける、extractを使っていらない部分の除去
    con = soup.find("span",class_="DataView-DataInfo-summary")
    con=soup.find("small",class_="DataView-DataInfo-summary-unit").extract()
    
    text=con.get_text()
    
    text= text.strip()
    
    
    print(text+"人です")
    

    이것을 실행하면

    확실히 취득할 수 있어, 공백등도 지울 수 있었습니다.

    그런 다음 이것을 discord의 bot 프로그램에 통합합니다.discord.py 에 들어 있는 루프 기능을 사용해 60초에 1회 루프, 그리고 그 안에서 지정한 시간이 되면 스크레이핑 해 텍스트 채널에 투고라고 하는 프로그램을 짜였습니다. 소스는 다음과 같다.

    bot.py
    #coding:UTF-8
    import discord
    from discord.ext import tasks
    from datetime import datetime
    import requests
    from bs4 import BeautifulSoup
    
    TOKEN = "hoge" #トークン
    CHANNEL_ID = hoge #チャンネルID 
    
    # 接続に必要なオブジェクトを生成
    client = discord.Client()
    
    # 60秒に一回ループ
    @tasks.loop(seconds=60)
    async def loop():    
        now = datetime.now().strftime('%H:%M')
    
        if now == '20:05':
            await client.wait_until_ready()
            channel = client.get_channel(CHANNEL_ID)
            #先ほどのコード(soup.py)
            res= requests.get("https://stopcovid19.metro.tokyo.lg.jp/cards/number-of-confirmed-cases/")
            soup = BeautifulSoup(res.text,"html.parser")
            con = soup.find("span",class_="DataView-DataInfo-summary")
            con=soup.find("small",class_="DataView-DataInfo-summary-unit").extract()
            text=con.get_text()
            text= text.strip() 
    
            await channel.send("本日の東京都の感染者数は"+text+"人です") 
    
     #おまけ部分。指定したワードに反応してコメントを返す機能       
    @client.event
    async def on_message(message):
        # メッセージ送信者がBotだった場合は無視
        if message.author.bot:
            return
        # 「新宿」と発言したら「密」が返ってくる
        if message.content == '新宿':
            await message.channel.send('密です')
    
        if message.content == '江戸川区':
            await message.channel.send('密です')
    
    #ループ処理実行
    loop.start()
    # Bot起動
    client.run(TOKEN)
    

    시간을 20:05로 하고 있는 것은, 이번 사용하고 있는 사이트의 감염자수의 갱신이 20시라고 추측했기 때문에.
    실행 결과


    ※사이트에는 20시라고 써 있었습니다만, 날에 의해 마을 마을로 이번은 10분 정도였기 때문에 이런 결과가 되었습니다. 설정 시각은 여유를 가지고 20시 30분이라도 좋을 것 같다.
    동작을 확인할 수 있었으므로 이것을 VPS Docker에서 시작합니다.

    Docker로 운송


    docker run -it --name hoge python /bin/bash에서 파이썬 환경 구축docker exec -it hoge bash에서 안에 들고 작업 시작.
    우선 pip에서 필요한 라이브러리를 설치.pip install beautifulsoup4pip install requestspip install discordvim없이 편집 할 수 없기 때문에apt-get updateapt-get install vim에 넣습니다.
    기본 시간대가 UTC이므로ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime이 명령을 사용하여 시간대를 변경합니다.
    그 후 적당하게 폴더 만들어 그 안에 bot.py 를 만들어 방금전의 소스를 복사합니다. 이것으로 완성.python bot.py 로 기동하면 discord상에 bot이 일어나, 지정 시각에 도내의 오늘의 코로나 감염자수를 보고해 줍니다!

    개선점



    이번은 사이트가 20시에 갱신된다고 추측해 결정 치고를 실시하고 있습니다만, 이상형은 사이트가 갱신되는 것과 동시에 스크래핑을 해 bot가 보고해 준다고 하는 형태입니다.
    루프 안에서, 그 루프로 취득해 온 녀석과 전회 취득한 데이터를 비교해 일치하면 그대로 다르면 갱신해 bot가 보고한다, 라고 하는 프로그램을 쓰면 할 수 있을 것 같다-라고 ​​생각했으므로 개선하면 또 다른 기사 에 함께 게시합니다.

    좋은 웹페이지 즐겨찾기