我正在编写一个依赖于Scrapy
模块的python应用程序。它在本地工作正常,但是当我从aws lambda测试控制台运行它时失败了。我的python项目有一个requirements.txt
文件,具有以下依赖性:
scrapy==1.6.0
我通过以下链接打包了所有依赖项:https://docs.aws.amazon.com/lambda/latest/dg/lambda-python-how-to-create-deployment-package.html。另外,我将源代码*.py
放在zip文件的根目录下。我的打包脚本可以在https://github.com/zhaoyi0113/quote-datalake/blob/master/bin/deploy.sh
中找到。
它基本上有两件事,首先运行命令pip install -r requirements.txt -t dist
,将所有依赖项下载到dist
目录。其次,将应用程序python源代码复制到dist
目录中。
通过terraform
完成部署,下面是配置文件。
provider "aws" {
profile = "default"
region = "ap-southeast-2"
}
variable "runtime" {
default = "python3.6"
}
data "archive_file" "zipit" {
type = "zip"
source_dir = "crawler/dist"
output_path = "crawler/dist/deploy.zip"
}
resource "aws_lambda_function" "test_lambda" {
filename = "crawler/dist/deploy.zip"
function_name = "quote-crawler"
role = "arn:aws:iam::773592622512:role/LambdaRole"
handler = "handler.handler"
source_code_hash = "${data.archive_file.zipit.output_base64sha256}"
runtime = "${var.runtime}"
}
它压缩目录并将文件上传到lambda。
我发现当有一条语句Unable to import module 'handler': cannot import name 'etree'
时,我在lambda import scrapy
中遇到了运行时错误。我没有在代码中使用etree
,所以我相信scrapy
使用了某些东西。
我的源代码可以在https://github.com/zhaoyi0113/quote-datalake/tree/master/crawler
上找到。只有两个简单的python文件。
如果我在本地运行它们,效果很好。该错误仅出现在lambda中。是否有将scrapy
打包为lambda的其他方法?
答案 0 :(得分:1)
您需要提供整个依赖关系树, scrapy 还具有一组依赖关系(它们也可能具有依赖关系)。
下载所有必需依赖项的最简单方法是使用pip
$ pip -t packages/ install scrapy
这会将 scrapy 及其所有依赖项下载到文件夹包中。
Scrapy具有lxml
和pyOpenSSL
作为依赖关系,其中包括已编译的组件。除非它们是静态编译的,否则可能会要求将所需的C库也安装在lambda VM上。
从lxml文档中需要:
也许尝试将这些安装添加到您的部署脚本中。您应该可以使用(我正在猜测软件包名称)yum -y install libxml2 libxslt
另一个好主意是在Amazon Linux EC2实例上测试您的脚本,因为它与Lambda所执行的环境非常接近。
答案 1 :(得分:1)
基于与Tim的交流,此问题是由本地和lambda之间的库版本不兼容引起的。
解决此问题的最简单方法是使用docker image lambci/lambda
通过以下命令构建软件包:
$ docker run -v $(pwd):/outputs -it --rm lambci/lambda:build-python3.6 pip install scrapy -t /outputs/