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 ...
Utilisez Lambda pour obtenir des données Yahoo! Weather (Tokyo) toutes les 6 heures.
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.
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
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')
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.
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é'
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
sam-app $sh deploy.sh
..
Successfully created/updated stack - weather-crawler
Accédez à la console AWS et exécutez!
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.
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.