[PYTHON] Web scraping à l'aide d'AWS lambda

Background Poursuite de FizzBuzz avec AWS Lambda. Cette fois, j'ai essayé d'obtenir des données à partir d'une page Web externe en grattant.

AWS Architecture archtecture.png

--S3 (stockage de données) --AWS Lambda (traitement des données) --Amazon Event Bridge (exécution périodique)

J'utilise trois services.

Setting

S3

Créez un compartiment pour stocker les données.

Saisissez uniquement le nom du compartiment et laissez les autres paramètres sur leurs valeurs par défaut. (Sélectionnez la région appropriée.)

La création du bucket est terminée.

Lambda

Créez un lambda pour le traitement des données.

Créez à partir de zéro, pas ... Ici, "s3-get-object-python" dans "Utilisation du dessin de conception" est utilisé.

Saisissez le nom de la fonction et le nom du rôle. Cette fois, nous téléchargerons le fichier sur S3, supprimez donc le modèle de stratégie «accès en lecture seule». Pour le déclencheur S3, entrez le compartiment que vous avez créé précédemment pour le nom du compartiment.

Après cela, entrez n'importe quel caractère dans l'option de préfixe **. ** ** Les caractères arbitraires mentionnés ici sont des caractères qui ne chevauchent pas le début du nom de fichier, bien que le fichier soit créé avec lambda. Ceci est important car si vous n'entrez pas ou n'entrez pas de caractères en double, vous déclencherez une boucle infinie vers ** lambda et encourrez une charge importante: scream: **.

Une autre solution de contournement consiste à ajouter des restrictions telles que la copie de type d'événement uniquement.

Après avoir terminé toutes les entrées, appuyez sur "Créer une fonction".

Un modèle sera créé, mais si vous poursuivez le développement, le déployez et le testez, une erreur d'autorisation se produira.

Paramètres S3

Tout d'abord, activez S3.

Si vous regardez la notification d'événement dans les propriétés du compartiment dans S3, vous pouvez voir qu'elle a été ajoutée.

Ajouter des autorisations à un rôle

Sélectionnez IAM → Rôle pour afficher la liste des rôles. Ici, sélectionnez le nom du rôle décrit précédemment lors de la création du lambda.

Appuyez sur "Joindre la politique" sans réfléchir.

Filtrez par "LambdaFull", sélectionnez "AWSLambdaFullAccess" et appuyez sur "Joindre la politique".

Ceci termine l'ajout des autorisations.

configuration de base

Le traitement a échoué lorsque la mémoire était petite. Mémoire: 256 Mo, régler le délai d'expiration à 10 secondes.

C'est ça.

Développement (envoyer le fichier)

Utilisez le package bote3 pour envoyer et recevoir des compartiments S3. Si vous sélectionnez s3-get-object-python lors de la création de lambda, il sera inclus. Si vous téléchargez le package depuis le début, la capacité de bote3 lui-même sera grande et elle sera de 10 Mo ou plus, il est donc préférable d'utiliser l'existant.

import json
import urllib.parse
import boto3
import datetime

def lambda_handler(event, context):

    try:
        # Get the object from the event and show its content type
        s3 = boto3.resource('s3')
    
        bucket = '[Nom du godet]'    
        key = 'test_{}.txt'.format(datetime.datetime.now().strftime('%Y-%m-%d-%H-%M-%S'))
        file_contents = 'Lambda test'  
        
        obj = s3.Object(bucket,key)
        obj.put( Body=file_contents )
        
    except Exception as e:
        print(e)
        raise e

Après le déploiement et les tests, les fichiers seront téléchargés dans le compartiment. De plus, bien qu'il s'agisse d'un paramètre d'événement de test, il démarrera même avec un json vide.

Développement (Web scraping)

Pour gratter, j'ai des demandes`` beautifulsoup, mais je dois télécharger le paquet installé par pip sur lambda.

La méthode consiste à installer le package dans le dossier avec pip et à compresser le dossier. Créez un fichier exécutable ici et copiez le code écrit en lambda.

mkdir packages
cd packages
pip install requests -t ./
pip install beautifulsoup -t ./
touch lambda_function.py

Le package est placé dans le projet. Ensuite, déplacez les dossiers et fichiers sous packages vers le articleStore un niveau supérieur. Ensuite, déployez et testez pour ajouter le fichier à S3.

Tout ce que vous avez à faire est de faire du web scraping. Ici, je vais essayer d'obtenir le Mainichi Shimbun Editorial daté d'aujourd'hui.

import json
import urllib.parse
import boto3
import datetime
from datetime import timedelta, timezone
import random
import os
import requests
from bs4 import BeautifulSoup

print('Loading function')

s3 = boto3.resource('s3')

def lambda_handler(event, context):
    # Get the object from the event and show its content type
    JST = timezone(timedelta(hours=+9), 'JST')
    dt_now = datetime.datetime.now(JST)
    date_str = dt_now.strftime('%Y année%m mois%jour j')

    response = requests.get('https://mainichi.jp/editorial/')

    soup = BeautifulSoup(response.text)
    pages = soup.find("ul", class_="list-typeD")

    articles = pages.find_all("article")
    
    links = [ "https:" + a.a.get("href") for a in articles if date_str in a.time.text ]
    
    for i, link in enumerate(links):
        bucket_name = "[Nom du godet]"
        folder_path = "/tmp/"
        filename = 'article_{0}_{1}.txt'.format(dt_now.strftime('%Y-%m-%d'), i + 1)
        
        try:
            bucket = s3.Bucket(bucket_name)
            
            with open(folder_path + filename, 'w') as fout:
                fout.write(extract_article(link))
            
            bucket.upload_file(folder_path + filename, filename)
            os.remove(folder_path + filename)
    
        except Exception as e:
            print(e)
            raise e

    return {
        "date" : dt_now.strftime('%Y-%m-%d %H:%M:%S')
    }

#Extraire l'éditorial
def extract_article(src):

    response = requests.get(src)
    soup = BeautifulSoup(response.text)

    text_area = soup.find(class_="main-text") 
    title = soup.h1.text.strip()
    sentence = "".join([txt.text.strip() for txt in text_area.find_all(class_="txt")])

    return title + "\n" + sentence

Cela ajoutera deux fichiers texte avec les articles extraits dans le compartiment S3 en sélectionnant «Déployer» -> «Test».

Cela fait longtemps, mais les réglages de Lambda sont complets.

Amazon EventBridge

J'ai pu le gérer, mais c'est vraiment fastidieux d'appuyer sur le bouton "test" tous les matins. Par conséquent, utilisez Amazon Event Bridge pour configurer une exécution périodique.

Amazon EventBridge → Événements → Sélectionnez les règles, Appuyez sur "Créer une règle".

Écrivez le nom et la description de la règle, et comme l'expression cron est exécutée à l'heure standard, exécutez-la comme 0 22 * *? * À 7h00, heure du Japon. Sélectionnez le nom lambda cible dans la cible et créez-le.

C'est ça.

Post-Scripting Comme plan après cela, je vais stocker les éditoriaux de plusieurs sociétés de journaux pendant un an et essayer l'apprentissage automatique. Ce serait bien si vous pouviez obtenir toutes les pages avec des demandes, mais si vous avez un site qui est chargé et répertorié (par exemple, Asahi Shimbun) lorsque la page se charge, vous devez contrôler le navigateur avec sélénium. Il y a.

Recommended Posts

Web scraping à l'aide d'AWS lambda
[Python] Scraping dans AWS Lambda
Web scraping avec Selenium (Python)
raclage Web
Récapitulatif si vous utilisez AWS Lambda (Python)
Tweet Récapitulatif WakaTime à l'aide d'AWS Lambda
[AWS] Utilisation de fichiers ini avec Lambda [Python]
[Débutant] Scrapage Web Python facile à comprendre à l'aide de Google Colaboratory
grattage Web (prototype)
Publiez régulièrement sur Twitter en utilisant AWS lambda!
Scraping à l'aide de Python
Exécutez régulièrement le scraping WEB avec AWS-Lambda + Python + Cron
J'ai essayé le web scraping en utilisant python et sélénium
Grattage sans serveur régulier avec AWS lambda + scrapy Part 1.8
Un chercheur d'une société pharmaceutique a résumé le raclage Web à l'aide de Python
Premiers pas avec le Web Scraping
Tweet d'AWS Lambda
Application Web utilisant Bottle (1)
Exemple d'utilisation de lambda
Essayez les destinations AWS Lambda
Développer, exécuter et déployer AWS Lambda à distance à l'aide de lambda-uploader
Vérifiez types_map lors de l'utilisation de mimetypes avec AWS Lambda (Python)
Comment configurer Layer sur Lambda à l'aide d'AWS SAM
J'ai essayé d'obtenir une AMI en utilisant AWS Lambda
Scraping à l'aide de Python 3.5 async / await
Développement d'applications WEB à l'aide de django-development partie 1-
L'implémentation la plus simple d'AWS Lambda
Enregistrez des images avec le web scraping
Scraping à l'aide de la syntaxe Python 3.5 Async
Points addictifs lors du téléchargement de fichiers à l'aide de boto sur AWS Lambda
Technologie de grattage WEB et préoccupations
Compromis dans le scraping et l'exploration Web
Essayez d'utiliser AWS SageMaker Studio
Grattage Web facile avec Scrapy
Collection d'images avec scraping Web
PyTorch avec AWS Lambda [importation Lambda]
Créez rapidement une API avec Python, lambda et API Gateway à l'aide d'AWS SAM
Web scraping débutant avec python
Bibliothèque de scraping Web utilisant des algorithmes Scrapely
Grattage de bande sur une seule ligne avec du tsé
J'ai essayé d'utiliser AWS Chalice
Créer une application Web de type Flask / Bottle sur AWS Lambda avec Chalice
J'ai arrêté une instance à un moment précis à l'aide d'AWS Lambda
Grattage sans serveur régulier avec AWS lambda + scrapy, partie 1
J'ai comparé Node.js et Python lors de la création d'une miniature à l'aide d'AWS Lambda
Faisons une discussion WEB en utilisant WebSocket avec AWS sans serveur (Python)!
[Python] J'ai écrit une API REST en utilisant AWS API Gateway et Lambda.
Développement d'une application WEB avec Django [Django startup]
Contre-mesures contre le proxy lors de l'utilisation de l'API WEB
Développement d'une application WEB avec Django [Ajout d'application]
Prise en charge de la variable d'environnement AWS Lambda
[AWS] Créer une API avec API Gateway + Lambda
Grattage WEB avec BeautifulSoup4 (page en couches)
Météorologie x Ruby ~ Grattage de rubis avec Mechanize ~
J'ai créé un robot pour publier sur Twitter en grattant sur le Web un site dynamique avec AWS Lambda (suite)
Gratter le classement Web d'Alexa avec pyQuery