[PYTHON] Grattage sans serveur régulier avec AWS lambda + scrapy Part 1.8

introduction

Pour écrire la conclusion en premier, je ne pouvais pas en arriver au point où cela fonctionne sur Lambda. Il existe d'autres méthodes, donc si cela fonctionne, je vais l'ajouter ou le publier dans un article séparé.

Cette fois, Dernière fois (1) Nous allons mettre le fichier weather_spider.py créé sur AWS lambda afin qu'il puisse être exécuté sans serveur. Cela fait un moment depuis la dernière fois, mais la raison est plus tard ...

Cible

Utilisez Lambda pour obtenir des données Yahoo! Weather (Tokyo) toutes les 6 heures.

Méthode

Cette fois, nous utiliserons le modèle d'application sans serveur (SAM) pour construire divers lambdas.

Veuillez consulter ici pour SAM.

Ce qui suit suppose que la commande aws et la commande sam peuvent être exécutées.

Essayer

1. Créez un projet SAM (sam dedans)

Cette fois, nous allons l'implémenter avec Python 3.7, spécifiez donc python 3.7 pour le runtime et sam dedans.

$ sam init --runtime python3.7
[+] Initializing project structure...

Project generated: ./sam-app

Steps you can take next within the project folder
===================================================
[*] Invoke Function: sam local invoke HelloWorldFunction --event event.json
[*] Start API Gateway locally: sam local start-api

Read sam-app/README.md for further instructions

[*] Project initialization is now complete

Un projet sam est créé en un instant comme celui-ci.

La structure des dossiers est la suivante.


sam-app
├── README.md
├── events
│   └── event.json
├── hello_world
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-37.pyc
│   │   └── app.cpython-37.pyc
│   ├── app.py
│   └── requirements.txt
├── template.yaml
└── tests
    └── unit
        ├── __init__.py
        ├── __pycache__
        │   ├── __init__.cpython-37.pyc
        │   └── test_handler.cpython-37.pyc
        └── test_handler.py

Copiez le yahoo_weather_crawl précédemment créé directement sous sam-app

$ cp -r yahoo_weather_crawl sam-app/

$ cd sam-app/
$ ls
README.md		hello_world		tests
events			template.yaml		yahoo_weather_crawl

2. Modifiez weather_spider.py

Ajoutez un gestionnaire afin que vous puissiez lancer lambda.

spider/weather_spider.py



# -*- coding: utf-8 -*-
import scrapy
from yahoo_weather_crawl.items import YahooWeatherCrawlItem
from scrapy.crawler import CrawlerProcess

# spider
class YahooWeatherSpider(scrapy.Spider):

    name = "yahoo_weather_crawler"
    allowed_domains = ['weather.yahoo.co.jp']
    start_urls = ["https://weather.yahoo.co.jp/weather/jp/13/4410.html"]

    #Processus d'extraction pour réponse
    def parse(self, response):
        #Date et heure de l'annonce
        yield YahooWeatherCrawlItem(announcement_date = response.xpath('//*[@id="week"]/p/text()').extract_first())
        table = response.xpath('//*[@id="yjw_week"]/table')

        #Boucle de date
        for day in range(2, 7):

            yield YahooWeatherCrawlItem(
                #Extraction de données
                date=table.xpath('//tr[1]/td[%d]/small/text()' % day).extract_first(),
                weather=table.xpath('//tr[2]/td[%d]/small/text()' % day).extract_first(),
                temperature=table.xpath('//tr[3]/td[%d]/small/font/text()' % day).extract(),
                rainy_percent=table.xpath('//tr[4]/td[%d]/small/text()' % day).extract_first(),
                )

    # lambda handler
    def lambda_handler(event,context):
        process = CrawlerProcess({
            'FEED_FORMAT': 'json',
            'FEED_URI': '/tmp/result.json'
        })

        process.crawl(YahooWeatherCrawler)
        process.start()
        print('crawl success')

3. Modifiez template.yaml

Modifiez le tamplate.yaml créé précédemment avec la commande sam init.

template.yaml


AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Yahoo weather crawler template on SAM

Globals:
  Function:
    Timeout: 3

Resources:
  WeatherCrawlerFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: ./yahoo_weather_crawl/spiders
      Handler: weather_spider.lambda_handler
      Runtime: python3.7
      Events:
        WeatherCrawlEvent:
          Type: Schedule
          Properties:
            #Exécuter toutes les 6 heures par jour
            Schedule: cron(0 */6 * * ? *)

Ici, ʻEvents` est chargé avec cron qui s'exécute toutes les 6 heures chaque jour. Assurez-vous de lancer à partir des événements Cloudwatch.

4. Créez un shell pour la construction (collectez les modules à déployer)

Collectez les modules nécessaires au déploiement sur AWS dans un dossier nommé build.

Mais avant cela, cette fois, j'importe scrapy et j'exécute Python, mais la bibliothèque dépendante de scrapy À l'intérieur, il y a une bibliothèque appelée lxml.

Si vous faites pip install scrapy, lxml sera installé automatiquement, mais Après le téléchargement vers AWS Lambda avec l'environnement d'exécution Python 3.7, le module ne peut pas être chargé tel quel. (Il m'a fallu beaucoup de temps pour lutter ici ...)

Par conséquent, cette fois, la sauce secrète (bibliothèque lxml compilée sur EC2, voir l'article pour plus de détails) créée par cet article s'appelle «lib». Enregistrez-le dans le dossier nommé et copiez-le dans le dossier de construction dans le shell de construction.

build.sh


# build

dir=yahoo_weather_crawl

echo 'Créer un environnement virtuel'
python3 -m venv .venv

echo 'Activer l'environnement virtuel'
. .venv/bin/activate

rm -rf ${dir}/build

#Créer un dossier de construction
echo '${dir}Construire'
mkdir ${dir}/build

#pip installer dans le dossier de construction
echo 'requirements.pip installer à partir de txt'
pip3 install -r ${dir}/requirements.txt -t ${dir}/build

#Copier du dossier lib vers le dossier de construction
echo 'Copiez les modules requis du dossier lib dans le dossier build'
cp -rf ./lib/* ${dir}/build

#Copie du fichier py
echo 'Copiez le fichier py dans le dossier de construction'
cp -f ${dir}/*.py ${dir}/build
cp -f ${dir}/spiders/*.py ${dir}/build

# echo 'Désactivez l'environnement virtuel'
deactivate

echo 'Construire terminé'

5. Créez un shell pour sam-deploy

Créez un shell pour le déploiement afin de pouvoir déployer à partir de la commande.

deploy.sh



# build
echo 'Construire Yahoo Weather Crawler'
sh build.sh

#Créer un compartiment S3 pour télécharger un modèle
#Le nom du bucket doit être unique dans le monde. Modifiez le nom du bucket si vous souhaitez le copier.
if  aws s3 ls "s3://weather-crawl-bucket" 2>&1 | grep -q 'NoSuchBucket' ; then
    echo "weather-crawl-Créez un seau."
    aws s3 mb s3://weather-crawl-bucket
else
    echo "weather_crawl-Videz le seau."
    aws s3 rm s3://weather-crawl-bucket --recursive
fi

#Créer un package pour le déploiement
#Téléchargez le package créé sur S3. Veuillez spécifier le nom du compartiment créé.
echo "Créez un package pour le déploiement."
aws cloudformation package --template-file template.yaml \
--output-template-file output-template.yaml \
--s3-bucket weather-crawl-bucket

#Déployer
aws cloudformation deploy --template-file output-template.yaml \
--stack-name weather-crawler \
--capabilities CAPABILITY_IAM

6. Déployer

sam-app $sh deploy.sh
..
Successfully created/updated stack - weather-crawler

7. Exécuter

Accédez à la console AWS et exécutez! スクリーンショット 2019-12-31 18.31.53.png

Cette fois, ImportError d'un autre module ... Construire localement sur un Mac semble un peu délicat, alors j'aimerais envisager une autre méthode.

À la fin

Cela fait plus d'un mois que j'ai décidé de publier un article sur Qiita chaque semaine, J'ai fini par n'écrire que trois articles cette année. (Une fois que vous êtes accro, vous ne pouvez pas sortir!)

l'année prochaine aussi? Nous continuerons à faire de notre mieux, alors merci.

Recommended Posts

Grattage sans serveur régulier avec AWS lambda + scrapy Part 1.8
Grattage sans serveur régulier avec AWS lambda + scrapy, partie 1
Grattage avec coquille tremblante
Application sans serveur avec AWS SAM! (APIGATEWAY + Lambda (Python))
[AWS] Play with Step Functions (SAM + Lambda) Part.3 (Branch)
Déployer la fonction Python 3 avec Serverless Framework sur AWS Lambda
[AWS] Play with Step Functions (SAM + Lambda) Part.1 (Basic)
[AWS] Play with Step Functions (SAM + Lambda) Part.2 (Paramètres)
Grattage avec Selenium + Python Partie 1
Grattage festif avec Python, scrapy
Déployer Django sans serveur avec Lambda
Grattage Web facile avec Scrapy
PyTorch avec AWS Lambda [importation Lambda]
Web scraping à l'aide d'AWS lambda
Grattage avec Selenium + Python Partie 2
[AWS] Créer une API avec API Gateway + Lambda
Notifier HipChat avec AWS Lambda (Python)
Comment créer une API de machine learning sans serveur avec AWS Lambda
Automatisez des tâches simples avec Python Part1 Scraping
[AWS] Associez Lambda et S3 à boto3
[Part1] Scraping avec Python → Organisez jusqu'à csv!
Connectez-vous à s3 avec AWS Lambda Python
[AWS] Faites des choses de type SSI avec S3 / Lambda
Touchez AWS avec Serverless Framework et Python
Je viens de faire FizzBuzz avec AWS Lambda
Exécutez régulièrement le scraping WEB avec AWS-Lambda + Python + Cron
LINE BOT avec Python + AWS Lambda + API Gateway
[AWS] Essayez de tracer API Gateway + Lambda avec X-Ray
J'ai essayé de connecter AWS Lambda à d'autres services
Automatisation de la construction de l'infrastructure avec CloudFromation + troposphère + AWS Lambda
Grattage au sélénium
Grattage avec Python
Grattage avec Python
Grattage avec du sélénium
Redémarrez avec Scrapy
Python: grattage partie 1
Python: grattage, partie 2
Je voulais utiliser la feuille de calcul Google avec AWS lambda, alors je l'ai essayé [Partie 2]
Pages HTML dynamiques créées avec AWS Lambda et Python
Scraping avec Python, publication sur TwitterBot, exécution régulière sur Heroku
Créer une fonction Lambda de version Python (+ couche Lambda) avec Serverless Framework
Créer une couche pour AWS Lambda Python dans Docker
Je veux AWS Lambda avec Python sur Mac!
Gérer la rétention des groupes de journaux Amazon CloudWatch avec AWS Lambda
Créez des tweets ordinaires comme une flotte avec AWS Lambda et Python