AWS Lambda - scrapy库无法正常工作(无法导入名称certificate_transparency)

时间:2017-12-28 08:49:30

标签: python scrapy pip aws-lambda

我想使用AWS Lambda来抓取网站。 爬虫代码使用Python并使用Pip提供的Scrapy库。

要运行lambda函数,我必须在公共Amazon Linux AMI版本中创建一个依赖项zip(此处仅为scrapy) - amzn-ami-hvm-2017.03.1.20170812-x86_64-gp2,按照their documentation here,添加lambda函数并上传它以创建lambda函数。

现在,当我调用lambda函数时,它给出了以下错误:

cannot import name certificate_transparency: ImportError
Traceback (most recent call last):
  File "/var/task/my_lambda_function.py", line 120, in my_lambda_handler
    return get_data_from_scrapy(username, password)
  File "/var/task/my_lambda_function.py", line 104, in get_data_from_scrapy
    process.crawl(MyScrapyFunction)
  File "/var/task/scrapy/crawler.py", line 167, in crawl
    crawler = self.create_crawler(crawler_or_spidercls)
  File "/var/task/scrapy/crawler.py", line 195, in create_crawler
    return self._create_crawler(crawler_or_spidercls)
  File "/var/task/scrapy/crawler.py", line 200, in _create_crawler
    return Crawler(spidercls, self.settings)
  File "/var/task/scrapy/crawler.py", line 52, in __init__
    self.extensions = ExtensionManager.from_crawler(self)
  File "/var/task/scrapy/middleware.py", line 58, in from_crawler
    return cls.from_settings(crawler.settings, crawler)
  File "/var/task/scrapy/middleware.py", line 34, in from_settings
    mwcls = load_object(clspath)
  File "/var/task/scrapy/utils/misc.py", line 44, in load_object
    mod = import_module(module)
  File "/usr/lib64/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
  File "/var/task/scrapy/extensions/memusage.py", line 16, in <module>
    from scrapy.mail import MailSender
  File "/var/task/scrapy/mail.py", line 22, in <module>
    from twisted.internet import defer, reactor, ssl
  File "/var/task/twisted/internet/ssl.py", line 59, in <module>
    from OpenSSL import SSL
  File "/var/task/OpenSSL/__init__.py", line 8, in <module>
    from OpenSSL import crypto, SSL
  File "/var/task/OpenSSL/crypto.py", line 12, in <module>
    from cryptography import x509
  File "/var/task/cryptography/x509/__init__.py", line 7, in <module>
    from cryptography.x509 import certificate_transparency
ImportError: cannot import name certificate_transparency

以下是我正在使用的依赖项/库版本(都是最新版本):

  • pip 9.0.1
  • Scrapy == 1.4.0
  • pyOpenSSL == 17.5.0
  • LXML == 4.1.1
  • 加密== 2.1.4

任何帮助将不胜感激。提前谢谢。

3 个答案:

答案 0 :(得分:4)

我不会将AWS Lambda用于此类复杂任务。你为什么选择它?如果因为它是免费的,你有几个更好的选择:

  • AWS为新帐户提供一年免费访问服务。
  • AWS Lightsail为您提供最低计划的免费月份。
  • PythonAnywhere.com为您提供免费帐户。我在PythonAnywhere上尝试过Scrapy,它运行得很好。请注意,&#34;连续&#34;免费帐户的运行时间最长为2小时,付费帐户的运行时间最长为6小时(根据他们的支持)。
  • ScrapingHub.com为您提供一个免费的抓取工具。查看名为&#34; 将Scrapy Spider部署到ScrapingHub的视频 &#34; - 该视频可在此课程下免费预览&#34; Scrapy: Powerful Web Scraping & Crawling with Python&#34;。

我希望这会有所帮助。如果您有任何疑问,请告诉我。

答案 1 :(得分:3)

我不知道您是否最终解决了这个问题,但是问题来自lxml库。它需要C依赖项才能正确构建,这给lambda带来了很多问题,因为它们依赖于OS。我正在通过无服务器的AWS部署scrapy,我用两件事来解决它:<ul style="width:100%"> <li>Lorem</li> <li>Ipsum</li> <li>Dolor</li> <li>Sit</li> <li>Amet</li> </ul> <ul> <li>Lorem</li> <li>Ipsum</li> <li>Dolor</li> <li>Sit</li> <li>Amet</li> </ul>插件和serverless-python-requirements设置。这会强制无服务器在Docker容器中构建软件包,从而提供正确的二进制文件。请注意,除了lxml可以在AWS Lambda上运行之外,这也是使NumPy,SciPy,Pandas等获得解决方案。这是我遵循的博客,以使其正常运行:https://serverless.com/blog/serverless-python-packaging/

如果您不想自己制作zip文件,则无服务器是很好的选择。如果这样做,这是一个堆栈溢出链接,该链接显示了如何使用lxml解决问题:AWS Lambda not importing LXML

答案 2 :(得分:0)

正如Ivan提到的,这里的问题来自于python包所需的c依赖关系

幸运的是,AWS发布了amazonlinux Docker映像,该映像几乎与Lambda函数使用的AMI相同,这是我自己使用的article,并对其进行了详细说明。

这是我用来构建Scrapy项目并将其打包为lambda的docker配置

FROM amazonlinux:latest
RUN yum -y install git \
    gcc \
    openssl-devel \
    bzip2-devel \
    libffi \
    libffi-devel \
    python3-devel \
    python37 \
    zip \
    unzip \
    && yum clean all

RUN python3 -m pip install --upgrade pip 

COPY src /io

CMD sh /io/package.sh

这是package.sh文件

#!/bin/bash

mkdir holder 
python3 -m pip install scrapy OTHER-REPOS -t holder
rm -f /packages/lambda.zip
cp -r /io/* holder
cd holder
zip -r /packages/lambda.zip *

这是我如何构建映像并与卷一起运行,以在完成后获取部署包zip文件

docker build -t TAG_NAME_HERE .
docker run --rm -v ${PWD}/deployment_package:/packages -t TAG_NAME_HERE

希望这会有所帮助。