AWS lambda+scrapy로 정기적으로 서버리스 스크래핑 1.8
14379 단어 serverless람다파이썬ScrapyAWS
소개
먼저 결론을 쓰면 Lambda에서 움직이는 곳까지 갈 수 없었습니다.
다른 방법의 대처는 있으므로, 그쪽이 잘 되면 추기, 혹은 다른 기사로서 들려고 생각합니다.
이번에는 마지막 (그 1) 작성한
weather_spider.py
를 AWSlambda에 올려서 서버리스로 실행할 수 있도록 하겠습니다.전회부터 상당한 시간이 비어 버렸습니다만, 이유는 나중에・・・.
목표
Lambda를 사용하여 Yahoo! 날씨 (도쿄)의 데이터를 6 시간 간격으로 가져옵니다.
방법
이번에는 서버리스 애플리케이션 모델(SAM)을 사용하여 lambda를 구축해 나갈 것입니다.
SAM에 대한 자세한 내용은 여기을 참조하십시오.
다음은 aws 명령, sam 명령을 실행할 수 있다고 가정합니다.
해보자
1.SAM Project 만들기(sam init)
이번에는 Python3.7에서 구현하기 때문에 runtime에 python3.7을 지정하여 sam init합니다.
$ 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
이런 식으로 한순간에 sam project가 만들어집니다.
폴더 구성은 이하.
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
sam-app 바로 아래에 마지막으로 만든 yahoo_weather_crawl 복사
$ cp -r yahoo_weather_crawl sam-app/
$ cd sam-app/
$ ls
README.md hello_world tests
events template.yaml yahoo_weather_crawl
2.weather_spider.py 수정
lambda에서 킥할 수 있도록 handler를 추가합니다.
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"]
# レスポンスに対する抽出処理
def parse(self, response):
# 発表日時
yield YahooWeatherCrawlItem(announcement_date = response.xpath('//*[@id="week"]/p/text()').extract_first())
table = response.xpath('//*[@id="yjw_week"]/table')
# 日付ループ
for day in range(2, 7):
yield YahooWeatherCrawlItem(
# データ抽出
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.template.yaml 수정
이전에
sam init
명령으로 만든 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:
#毎日6時間おきに実行
Schedule: cron(0 */6 * * ? *)
여기에서는
Events
에 매일 6 시간 간격으로 실행하는 cron을 넣고,Cloudwatch 이벤트에서 시작하도록 합니다.
4. build (배포 할 모듈을 모으기) 용 쉘 만들기
AWS에 배포할 때 필요한 모듈을 build라는 폴더에 연결합니다.
하지만 그 전에 이번에 scrapy를 가져오고 파이썬을 실행하지만 scrapy 종속 라이브러리
안에
lxml
라는 라이브러리가 있습니다.pip install scrapy
그렇다면 lxml도 자동으로 설치됩니다.Python3.7 런타임의 AWS Lambda에 업로드하면 그대로 모듈을 로드할 수 없습니다.
(여기에 고전하고, 꽤 시간이 걸렸습니다・・・.)
따라서 이번에는 이 기사에서 만든 비전 소스 (EC2에서 컴파일 된 lxml 라이브러리, 자세한 내용은 기사 참조)를
lib
라는 폴더에 저장하고 build 셸의 build 폴더에 복사 해야 합니다.build.sh
# build
dir=yahoo_weather_crawl
echo '仮想環境を作成します'
python3 -m venv .venv
echo '仮想環境を有効化します'
. .venv/bin/activate
rm -rf ${dir}/build
# buildフォルダの作成
echo '${dir}をbuildします'
mkdir ${dir}/build
# buildフォルダにpip install
echo 'requirements.txtからpip installします'
pip3 install -r ${dir}/requirements.txt -t ${dir}/build
# libフォルダからbuildフォルダへコピー
echo 'libフォルダからbuildフォルダへ必要モジュールをコピーします'
cp -rf ./lib/* ${dir}/build
# pyファイルのコピー
echo 'pyファイルをbuildフォルダにコピーします'
cp -f ${dir}/*.py ${dir}/build
cp -f ${dir}/spiders/*.py ${dir}/build
# echo '仮想環境を無効化します'
deactivate
echo 'ビルドが完了しました'
5.sam-deploy에 대한 쉘 만들기
명령에서 배포할 수 있도록 deploy용 셸을 만듭니다.
deploy.sh
# build
echo 'YahooWeatherCrawlerをビルドします'
sh build.sh
# templateをuploadするためのS3バケットの作成
# バケット名は世界中で一意にする必要があるので、コピペで作成する場合はバケット名を変更してください。
if aws s3 ls "s3://weather-crawl-bucket" 2>&1 | grep -q 'NoSuchBucket' ; then
echo "weather-crawl-bucketを作成します。"
aws s3 mb s3://weather-crawl-bucket
else
echo "weather_crawl-bucketを空にします。"
aws s3 rm s3://weather-crawl-bucket --recursive
fi
# デプロイ用パッケージの作成
# 作成されたパッケージをS3にuploadします。作成したバケット名を指定してください。
echo "デプロイ用のパッケージを作成します。"
aws cloudformation package --template-file template.yaml \
--output-template-file output-template.yaml \
--s3-bucket weather-crawl-bucket
# デプロイ
aws cloudformation deploy --template-file output-template.yaml \
--stack-name weather-crawler \
--capabilities CAPABILITY_IAM
6. 배포
sam-app $sh deploy.sh
..
Successfully created/updated stack - weather-crawler
7. 실행
AWS 콘솔로 이동하여 실행!
이제 다른 모듈의 ImportError ...
Mac의 로컬에서 빌드하는 것은 조금 힘들 것 같기 때문에 다른 방법을 생각하고 싶습니다.
끝에
매주 Qiita에 기사를 올리기로 결정한 지 한 달 이상 지났지만,
올해는 결국 세 기사밖에 걸리지 않았습니다. (한 번 빠지면 빠질 수 없다!)
내년도? 계속해서 노력해 가기 때문에, 잘 부탁드리겠습니다.
Reference
이 문제에 관하여(AWS lambda+scrapy로 정기적으로 서버리스 스크래핑 1.8), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/rkhcx/items/2aa5e458ea04c0caddaf텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)