Um die Schlussfolgerung zuerst zu schreiben, konnte ich nicht an den Punkt kommen, an dem es auf Lambda funktioniert. Es gibt andere Methoden. Wenn das funktioniert, werde ich es hinzufügen oder als separaten Artikel veröffentlichen.
Diesmal Letztes Mal (1) Wir werden die erstellte weather_spider.py
auf AWS lambda platzieren, damit sie serverlos ausgeführt werden kann.
Es ist eine Weile her seit dem letzten Mal, aber der Grund ist später ...
Verwenden Sie Lambda, um alle 6 Stunden Yahoo! Wetterdaten (Tokio) abzurufen.
Dieses Mal werden wir das Serverless Application Model (SAM) verwenden, um verschiedene Lambdas zu erstellen.
Informationen zu SAM finden Sie unter hier.
Im Folgenden wird davon ausgegangen, dass der Befehl aws und der Befehl sam ausgeführt werden können.
Dieses Mal werden wir es mit Python 3.7 implementieren, also geben Sie Python 3.7 für Runtime und Sam an.
$ 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
Ein Sam-Projekt wird in einem solchen Moment erstellt.
Die Ordnerstruktur ist wie folgt.
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
Kopieren Sie das zuvor erstellte yahoo_weather_crawl direkt unter sam-app
$ cp -r yahoo_weather_crawl sam-app/
$ cd sam-app/
$ ls
README.md hello_world tests
events template.yaml yahoo_weather_crawl
Fügen Sie einen Handler hinzu, damit Sie von Lambda treten können.
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"]
#Extraktionsprozess für die Antwort
def parse(self, response):
#Datum und Uhrzeit der Ankündigung
yield YahooWeatherCrawlItem(announcement_date = response.xpath('//*[@id="week"]/p/text()').extract_first())
table = response.xpath('//*[@id="yjw_week"]/table')
#Datumsschleife
for day in range(2, 7):
yield YahooWeatherCrawlItem(
#Datenextraktion
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')
Ändern Sie die zuvor mit dem Befehl "sam init" erstellte Datei "tamplate.yaml".
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:
#Laufen Sie alle 6 Stunden täglich
Schedule: cron(0 */6 * * ? *)
Hier habe ich einen Cron platziert, der jeden Tag alle 6 Stunden in "Events" läuft. Stellen Sie sicher, dass Sie von Cloudwatch-Ereignissen aus starten.
Sammeln Sie die für die Bereitstellung in AWS erforderlichen Module in einem Ordner mit dem Namen build.
Aber vorher importiere ich diesmal Scrapy und führe Python aus, aber Scrapys abhängige Bibliothek Im Inneren befindet sich eine Bibliothek namens "lxml".
Wenn Sie "pip install Scrapy" ausführen, wird lxml automatisch installiert, aber Nach dem Hochladen auf AWS Lambda mit Python 3.7-Laufzeit kann das Modul nicht so geladen werden, wie es ist. (Ich habe lange gebraucht, um hier zu kämpfen ...)
Daher heißt die von diesem Artikel erstellte geheime Sauce (auf EC2 kompilierte lxml-Bibliothek, siehe Artikel) dieses Mal "lib". Speichern Sie es im benannten Ordner und kopieren Sie es in den Build-Ordner innerhalb der Build-Shell.
build.sh
# build
dir=yahoo_weather_crawl
echo 'Erstellen Sie eine virtuelle Umgebung'
python3 -m venv .venv
echo 'Virtuelle Umgebung aktivieren'
. .venv/bin/activate
rm -rf ${dir}/build
#Build-Ordner erstellen
echo '${dir}Bauen'
mkdir ${dir}/build
#Pip-Installation im Build-Ordner
echo 'requirements.pip von txt installieren'
pip3 install -r ${dir}/requirements.txt -t ${dir}/build
#Kopieren Sie aus dem lib-Ordner in den Build-Ordner
echo 'Kopieren Sie die erforderlichen Module aus dem lib-Ordner in den Build-Ordner'
cp -rf ./lib/* ${dir}/build
#Kopie der py-Datei
echo 'Kopieren Sie die py-Datei in den Build-Ordner'
cp -f ${dir}/*.py ${dir}/build
cp -f ${dir}/spiders/*.py ${dir}/build
# echo 'Deaktivieren Sie die virtuelle Umgebung'
deactivate
echo 'Build abgeschlossen'
Erstellen Sie eine Shell für die Bereitstellung, damit Sie sie über den Befehl bereitstellen können.
deploy.sh
# build
echo 'Erstellen Sie Yahoo Weather Crawler'
sh build.sh
#Erstellen eines S3-Buckets zum Hochladen einer Vorlage
#Der Bucket-Name muss weltweit eindeutig sein. Ändern Sie daher den Bucket-Namen, wenn Sie ihn kopieren möchten.
if aws s3 ls "s3://weather-crawl-bucket" 2>&1 | grep -q 'NoSuchBucket' ; then
echo "weather-crawl-Erstellen Sie einen Eimer."
aws s3 mb s3://weather-crawl-bucket
else
echo "weather_crawl-Leeren Sie den Eimer."
aws s3 rm s3://weather-crawl-bucket --recursive
fi
#Erstellen eines Pakets für die Bereitstellung
#Laden Sie das erstellte Paket in S3 hoch. Bitte geben Sie den erstellten Bucket-Namen an.
echo "Erstellen Sie ein Paket für die Bereitstellung."
aws cloudformation package --template-file template.yaml \
--output-template-file output-template.yaml \
--s3-bucket weather-crawl-bucket
#Bereitstellen
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
Gehen Sie zur AWS-Konsole und starten Sie!
Diesmal ImportError eines anderen Moduls ... Das lokale Erstellen auf einem Mac scheint etwas schwierig zu sein, daher möchte ich eine andere Methode in Betracht ziehen.
Es ist über einen Monat her, seit ich beschlossen habe, jede Woche einen Artikel über Qiita zu veröffentlichen. Ich habe dieses Jahr nur drei Artikel geschrieben. (Sobald Sie süchtig sind, können Sie nicht mehr raus!)
nächstes Jahr auch? Wir werden weiterhin unser Bestes geben, also danke.
Recommended Posts