Utilisez AWS lambda pour récupérer les actualités et notifier régulièrement LINE des mises à jour [python]

introduction

Ceci est mon premier message posté. Je suis un étudiant qui étudie la programmation depuis environ six mois, mais j'aimerais publier petit à petit ce que j'ai appris, alors je le posterai. Je pense qu'il y a beaucoup de points désordonnés et sales tels que la façon d'écrire le code, alors n'hésitez pas à le souligner.

Objectifs / procédures

Comme le titre l'indique, utilisez régulièrement un outil appelé lambda sur AWS (Yahoo News Articles) ( Grattage toutes les 6 heures) et utilisation de l 'API de messagerie LINE pour les articles mis à jour dans votre compte LINE Le but est de vous avertir. L'environnement de développement utilise cloud9 en tenant compte de la coopération avec lambda.

Concernant la procédure (1) Obtenez 20 titres d'articles et URL à partir du Site d'actualités en utilisant le module Beautiful Soup de Python, et l'URL est AWS Ecrivez dans le fichier csv placé dans S3. (La partie à écrire se fait à la fin du programme.) (2) Comparez l'url de l'exécution précédente (lire csv depuis S3) avec l'url acquise cette fois pour trouver la mise à jour. (3) Notifiez le titre et l'url de l'article mis à jour à l'aide de l'API de messagerie LINE. Ce sera dans l'ordre.

Pour l'API de messagerie LINE, Surveiller les mises à jour de la page Web avec LINE BOT Scraping avec BeautifulSoup est Web scraping avec BeautifulSoup Pour lire et écrire le fichier csv S3, code Python pour simplement lire le fichier CSV AWS S3 et [Ecrire une trame de données Pandas au format CSV sur S3]( J'ai fait référence à l'article autour de https://www.jitsejan.com/write-dataframe-to-csv-on-s3.html).

code

import urllib.request
from bs4 import BeautifulSoup
import csv
import pandas as pd
import io
import boto3
import s3fs
import itertools
from linebot import LineBotApi
from linebot.models import TextSendMessage

def lambda_handler(event, context):
    
    url = 'https://follow.yahoo.co.jp/themes/051839da5a7baa353480'
    html = urllib.request.urlopen(url)
    #perspective html
    soup = BeautifulSoup(html, "html.parser")
    
    
    def news_scraping(soup=soup):
        """
Obtenir le titre et l'URL de l'article
        """
        title_list = []
        titles = soup.select('#wrapper > section.content > ul > li:nth-child(n) > a.detailBody__wrap > div.detailBody__cnt > p.detailBody__ttl')
    
        for title in titles:
            title_list.append(title.string)
    
        url_list = []   
        urls = soup.select('#wrapper > section.content > ul > li:nth-child(n) > a.detailBody__wrap')
        
        for url in urls:
            url_list.append(url.get('href'))
       
        return title_list,url_list
        
    def get_s3file(bucket_name, key):
        """
Lire csv depuis S3
        """
        s3 = boto3.resource('s3')
        s3obj = s3.Object(bucket_name, key).get()
    
        return io.TextIOWrapper(io.BytesIO(s3obj['Body'].read()))
        
    def write_df_to_s3(csv_list):
        """
Écrire dans S3
        """
        csv_buffer = io.StringIO()
        csv_list.to_csv(csv_buffer,index=False,encoding='utf-8-sig')
        s3_resource = boto3.resource('s3')
        s3_resource.Object('Nom du godet','nom de fichier').put(Body=csv_buffer.getvalue())
    
    def send_line(content):
        access_token = ********
        #Remplissez le jeton d'accès à la chaîne
        line_bot_api = LineBotApi(access_token)
        line_bot_api.broadcast(TextSendMessage(text=content))
    
    ex_csv =[]
    #Saisissez l'URL du scraping précédent
    for rec in csv.reader(get_s3file('Nom du godet', 'nom de fichier')):
        ex_csv.append(rec)
    
    ex_csv = ex_csv[1:]
    #index=Il aurait dû être écrit False, mais l'index 0 au début de la lecture csv(?)Était écrit
    ex_csv = list(itertools.chain.from_iterable(ex_csv))
    #Étant donné que le csv lu était un tableau à deux dimensions, il a été converti en un
    
    title,url = news_scraping()
    #Exécution de grattage
    csv_list = url
    
    #ex_Extraire les mises à jour en comparant avec csv
    for i in range(20):
        if csv_list[i] in ex_csv[0]:
        #Je l'ai utilisé parce que ça ne correspond pas exactement
            num = i
        #ex_L'article au début de csv est csv_Découvrez à quel numéro dans la liste il correspond
            break
        else:
            num = 'all'

    if num == 'all':
        send_list = [None]*2*20
        send_list[::2] = title
        send_list[1::2] = url
        send_list = "\n".join(send_list)
    #Insérez le titre et l'URL en alternance, puis interrompez
    
    elif num == 0:
        send_list = 'Pas de nouvelles'
    
    else:
        send_list = [None]*2*num
        send_list[::2] = title[:num]
        send_list[1::2] = url[:num]
        send_list = "\n".join(send_list)
    ##Insérez le titre et l'URL en alternance, puis interrompez
    
    send_line(send_list)
    
    csv_list = pd.DataFrame(csv_list)
    #Si vous écrivez dans S3 sous forme de liste, une erreur se produira, alors convertissez le type de données.
    write_df_to_s3(csv_list)
    #CSV sur S3_Rédiger la liste et terminer

Voilà pour le code. (Il était préférable de définir une fonction où send_list est créé à partir de num) Ensuite, déployez-le sur distant et définissez l'exécution périodique dans Amazon CloudWatch Events. Je pense qu'il est préférable de planifier avec Cron expression pour s'exécuter à des intervalles de temps spécifiques. Vous devez être prudent car vous devez accorder des droits d'accès à S3 avec IAM.

en conclusion

La lecture et l'écriture de csv de S3 ne se sont pas déroulées comme prévu. En particulier, il semble y avoir place à l'amélioration, comme le fait qu'il soit devenu un tableau bidimensionnel lors de l'écriture.

En fait, j'avais déjà pratiqué le grattage avec du sélnium, du chrome sans tête et du lambda (en plus d'utiliser lambda pour la première fois, j'ai eu beaucoup d'erreurs liées au chrome binaire et j'ai eu du mal). Par conséquent, j'ai pu écrire le code en un temps relativement court cette fois. Cela dit, c'est beaucoup plus de travail que le grattage local. J'ai omis comment utiliser lambda ici, mais c'est assez déroutant, alors veuillez vous référer à d'autres articles.

Récemment, j'ai travaillé sur django et Twitter API, donc si je remarque quelque chose ici, je le posterai à nouveau.

Merci beaucoup.

Recommended Posts

Utilisez AWS lambda pour récupérer les actualités et notifier régulièrement LINE des mises à jour [python]
Utilisons AWS Lambda pour créer un mécanisme pour notifier Slack lorsque la valeur surveillée par CloudWatch est dépassée sur Python
Une histoire sur l'écriture d'AWS Lambda et de devenir un peu accro aux valeurs par défaut des arguments Python
[Python] Laissez LINE vous informer quotidiennement du classement des résultats de recherche sur votre site.
Résumé de l'étude de Python pour utiliser AWS Lambda
[Python] Créez un script qui utilise FeedParser et LINE Notify pour informer LINE des dernières informations sur le nouveau virus corona du ministère de la Santé, du Travail et des Affaires sociales.
Instructions d'utilisation de l'interface de ligne de commande AWS (Python / awscli) sous Mac OS X
Déplacer régulièrement les journaux CloudWatch vers S3 avec Lambda
Grattage sans serveur régulier avec AWS lambda + scrapy, partie 1
Mettez à jour les données en les téléchargeant sur s3 d'aws avec une commande, et supprimez les données utilisées (en chemin)
Différentes façons de lire la dernière ligne d'un fichier csv en Python
Exécutez régulièrement des programmes Python sur AWS Lambda
Envoyer un message à LINE avec Python (LINE Notify)
Je souhaite utiliser Python dans l'environnement de pyenv + pipenv sous Windows 10
Utilisez libsixel pour générer Sixel en Python et générer le graphe Matplotlib vers le terminal.
Créez un environnement python pour apprendre la théorie et la mise en œuvre de l'apprentissage profond
[Python] Un programme qui calcule le nombre de mises à jour des enregistrements les plus élevés et les plus faibles
Prise en compte des forces et faiblesses de Python
J'ai essayé d'utiliser Twitter Scraper avec AWS Lambda et cela n'a pas fonctionné.
[Introduction aux statistiques] Quel type de distribution est la distribution t, la distribution chi carré et la distribution F? Un petit résumé de l'utilisation de [python]
[Python3] Prenez une capture d'écran d'une page Web sur le serveur et recadrez-la davantage
C'était une vie que je voulais faire de l'OCR sur AWS Lambda pour localiser les personnages.
Utilisez AWS Lambda + LINE Notify pour avertir LINE de ne pas oublier votre parapluie lorsque vous rentrez chez vous
Une petite histoire à savoir comme un point addictif lors de l'écriture d'applications Twilio à l'aide de Python sur AWS Lambda
Prise en charge de l'environnement d'exécution Python 2.7 sur AWS Lambda (à partir de 2020.1)
Je veux AWS Lambda avec Python sur Mac!
Procédure de création d'un Line Bot sur AWS Lambda
Note Python: Le mystère de l'attribution d'une variable à une variable
Utilisez Python pour surveiller Windows et Mac et collecter des informations sur les applications sur lesquelles vous travaillez
[C / C ++] Passez la valeur calculée en C / C ++ à une fonction python pour exécuter le processus et utilisez cette valeur en C / C ++.
Récupérez la chaîne correspondante dans l'expression régulière et réutilisez-la lors du remplacement sur Python3
Je veux trouver l'intersection d'une courbe de Bézier et d'une ligne droite (méthode de découpage de Bézier)
Notification Slack lorsqu'un mot spécifique est murmuré sur Twitter en utilisant Heroku avec python
J'ai créé une fonction pour découper l'image de python openCV, alors veuillez l'utiliser.
Grattage avec Python + Selenium pour ajouter des produits Apple reconditionnés à votre panier et notifier en ligne
[Python] Un programme pour trouver le nombre de pommes et d'oranges qui peuvent être récoltées
Comment obtenir les informations des organisations, Cost Explorer d'un autre compte AWS avec Lambda (python)
Publié en tant que pièce jointe à Slack sur AWS Lambda (Python)
Comment utiliser la méthode __call__ dans la classe Python
[Hyperledger Iroha] Remarques sur l'utilisation du SDK Python
[Python] Résumé de l'utilisation des fonctions de fractionnement et de jointure
Installez pyenv sur MacBookAir et basculez Python à utiliser
[Introduction à AWS] Mémorandum de création d'un serveur Web sur AWS
Publiez régulièrement des images de Papillon sur Python + AWS Lambda + Slack
Je veux connaître la nature de Python et pip
[Python] Permet d'importer les packages pip3 sur AWS Lambda
Écrivez un script dans Shell et Python pour vous avertir dans Slack lorsque le processus est terminé
Traitez le fichier gzip UNLOADed avec Redshift avec Python de Lambda, gzipez-le à nouveau et téléchargez-le sur S3
[Python] Le rôle de l'astérisque devant la variable. Divisez la valeur d'entrée et affectez-la à une variable
[Python] J'ai essayé de créer un programme simple qui fonctionne sur la ligne de commande en utilisant argparse
L'histoire du retour au front pour la première fois en 5 ans et de la refactorisation de Python Django
[Python] Comment utiliser l'instruction for. Une méthode d'extraction en spécifiant une plage ou des conditions.
Apprenez le flux de l'estimation bayésienne et comment utiliser Pystan grâce à un modèle de régression simple
Je veux clarifier la question de la méthode "__init__" et de l'argument "self" de la classe Python.
Comment utiliser Python lambda
[Python scraping] Affiche l'URL et le titre du site contenant un mot-clé spécifique dans un fichier texte
À propos de l'erreur que j'ai rencontrée en essayant d'utiliser Adafruit_DHT à partir de Python sur Raspberry Pi