[PYTHON] Essayez d'automatiser la surveillance du nombre de Qiita avec Lambda + DynamoDB + CloudWatch

Cet article est un relais du "Calendrier de l'Avent du Nouvel An 2020 TechConnect!" de Link Information System Ceci est un article. TechConnect! Est un calendrier de l'Avent à démarrage automatique qui est relayé par un groupe autodidacte appelé engineer.hanzomon. (Cliquez ici pour le lien système d'information Facebook (https://ja-jp.facebook.com/lis.co.jp/))

Cet article est pour le 7ème jour, 1/15 (mercredi).


Article précédent Je le fais aussi, mais je suis devenu une personne chargée de compter le nombre de likes de notre ad-care. (Je n'ai pas encore rédigé d'article sur l'ad-care, mais je le collectionne avec de l'art de la coquille) Donc, de toute façon, si le nombre de likes à automatiser dépasse un certain nombre, j'ai pensé que ce serait bien si je le notifiais comme un jalon Qiita ~~ Ce serait amusant ~~, j'ai donc décidé de l'exécuter sur AWS Lambda.

En ce qui concerne la mise en œuvre, comme les articles précédents, la page d'accueil Adcare est grattée pour collecter les URL des articles, et c'est comme obtenir le nombre de likes avec l'API Qiita. D'abord à partir de la fonction Lambda qui collecte les ID d'article

code
import os
import requests
import boto3
from selenium import webdriver
from bs4 import BeautifulSoup
from urllib.parse import urljoin

def lambda_handler(event, context):
    api_endpoint = 'https://qiita.com/api/v2/'

    try:
        dynamoDB = boto3.resource("dynamodb")
        advent_calendar = dynamoDB.Table("advent_calendar")

        options = webdriver.ChromeOptions()
        options.binary_location = "/opt/bin/headless-chromium"

        options.add_argument("--headless")
        options.add_argument("--disable-gpu")
        options.add_argument("--window-size=1280x1696")
        options.add_argument("--disable-application-cache")
        options.add_argument("--disable-infobars")
        options.add_argument("--no-sandbox")
        options.add_argument("--hide-scrollbars")
        options.add_argument("--enable-logging")
        options.add_argument("--log-level=0")
        options.add_argument("--single-process")
        options.add_argument("--ignore-certificate-errors")
        options.add_argument("--homedir=/tmp")

        driver = webdriver.Chrome(executable_path="/opt/bin/chromedriver", options=options)
        driver.get(os.environ['TARGET_URL'])
        soup = BeautifulSoup(driver.page_source, 'html.parser')

        item = soup.find('div', id='personal-public-article-body')
        tables = item.find_all('tbody')
        for table in tables:
            rows = table.find_all('tr')
            for row in rows:
                user_id = row.find_all('td')[1].text
                tmp = row.find_all('td')[2].find('a')['href']
                item_id = tmp[tmp.find('items/'):]
                response = advent_calendar.get_item(
                    Key={
                        'user_id': user_id,
                        'item_id': item_id
                    }
                )
                if 'Item' not in response:
                    advent_calendar.put_item(
                        Item = {
                            "user_id": user_id,
                            "item_id": item_id,
                            'likes': 0
                        }
                    )
    except Exception as e:
        print(e)
    finally:
        driver.quit()
    return
Enregistrez à l'avance les bibliothèques et les pilotes chromés requis dans Lambda Layers. Enregistrez l'ID d'article obtenu dans DynamoDB. Le nombre de likes est également initialisé ici. Exécutez cette fonction Lambda toutes les heures sur un événement CloudWatch.

Ainsi, la fonction qui émet l'API Qiita pour cet ID d'article collecté et obtient le nombre de likes est la suivante

code
import os
import boto3
import requests
from urllib.parse import urljoin
import smtplib
from email.message import EmailMessage

def lambda_handler(event, context):
    api_endpoint = 'https://qiita.com/api/v2/'
    headers = {'Authorization': 'Bearer ' + os.environ['QIITA_AUTH']}

    dynamoDB = boto3.resource("dynamodb")
    advent_calendar = dynamoDB.Table("advent_calendar")

    try:
        smtp = smtplib.SMTP_SSL(os.environ['SMTP_HOST'], int(os.environ['SMTP_PORT']))
        smtp_user = os.environ['SMTP_USER']
        smtp_pass = os.environ['SMTP_PASS']
        message = EmailMessage()
        message['From'] = os.environ['FROM_ADDRESS']
        message['To'] = os.environ['TO_ADDRESS']
        message['Subject'] = 'Adcare comme la surveillance'
        smtp.login(smtp_user, smtp_pass)

        response = advent_calendar.scan()
        for i in response['Items']:
            user_id = i['user_id']
            item_id = i['item_id']
            old_likes = int(i['likes'])
            item_url = urljoin(api_endpoint, item_id)
            item_detail = requests.get(item_url, headers=headers).json()
            
            title = item_detail['title']
            url = item_detail['url']
            new_likes = int(item_detail['likes_count'])
            comments = int(item_detail['comments_count'])
            stockers_url = urljoin(api_endpoint, item_id + '/stockers?per_page=100')
            stockers = len(requests.get(stockers_url, headers=headers).json())
            
            if old_likes < 100 and new_likes >= 100:
                message.set_content(user_id+"Article ""+title+"("+url+")A dépassé 100 likes")
                smtp.send_message(message)
            elif old_likes < 50 and new_likes >= 50:
                message.set_content(user_id+"Article ""+title+"("+url+")A dépassé 50 likes")
                smtp.send_message(message)
            elif old_likes < 30 and new_likes >= 30:
                message.set_content(user_id+"Article ""+title+"("+url+")A dépassé 30 likes")
                smtp.send_message(message)
            elif old_likes < 10 and new_likes >= 10:
                message.set_content(user_id+"Article ""+title+"("+url+")A dépassé 10 likes")
                smtp.send_message(message)
            
            advent_calendar.put_item(
                Item = {
                    "user_id": user_id,
                    "item_id": item_id,
                    "likes" : new_likes,
                    "comments" : comments,
                    "stockers" : stockers
                }
            )
    except Exception as e:
        print(e)
    finally:
        smtp.close()
    return
Scannez DynamoDB pour obtenir l'ID de l'article, émettez l'API Qiita dessus, comparez-le au nombre de likes obtenus la dernière fois, et la partie jugement est très approximative, mais si elle dépasse le seuil, elle sera envoyée par courrier. Je ne vous avertirai pas après ~~ 100, mais je ne l'aimerai pas tellement ~~ Ce gars s'exécute toutes les minutes à CloudWatch Event.

En fait, je voulais envoyer une notification à Microsoft Teams, qui est utilisée comme notre chat interne, mais je ne pouvais pas m'en rendre compte car j'ai été pris dans notre authentification en deux étapes avec l'authentification Office 365 ... Actuellement, je vole juste vers mon adresse e-mail. J'ai pensé essayer de le transférer automatiquement dans Outlook, mais je n'ai pas pu le transférer en raison d'un manque d'autorité. Je me demande ce que c'est.


Il y a une légère sensation d'une seule main, mais j'ai pu automatiser la collecte du nombre de likes. Je me demande si je vais extraire les données de DynamoDB et obtenir le résultat final lorsque le calendrier est terminé et qu'un paragraphe est atteint. Au début, je pensais utiliser l'agent HTTP de ZABBIX, mais comme le niveau gratuit EC2 a disparu, j'ai décidé d'utiliser Lambda + DynamoDB. Le cadre libre est le meilleur.

Demain, c'est @ h-yamasaki.


1/17 De plus, modifié pour collecter le nombre de commentaires et le nombre d'actions, le nombre d'émissions d'API a augmenté, il semblait donc que la limite supérieure de 1000 fois par heure serait capturée, donc l'intervalle de surveillance de CloudWatch Event a été changé de 1 minute à 5 minutes

Recommended Posts

Essayez d'automatiser la surveillance du nombre de Qiita avec Lambda + DynamoDB + CloudWatch
Essayez d'automatiser le démarrage / l'arrêt des instances EC2 avec AWS Lambda
Faites fonctionner Dynamodb depuis Lambda comme SQL
Manipulation des données DynamoDB avec Lambda (Node et Python)
API REST facile avec API Gateway / Lambda / DynamoDB
Essayez d'attribuer ou de changer avec Python: lambda
[AWS SAM] Créer une API avec DynamoDB + Lambda + API Gateway