安装Scrapy出现报错:MemoryError: Cannot allocate write+execute memory for ffi.callback().

安装Scrapy出现报错:MemoryError: Cannot allocate write+execute memory for ffi.callback().

如果存在报错,不要贸然尝试,请到官方Install页面指导下进行:https://docs.scrapy.org/en/latest/intro/install.html#。或者查看我的另一篇博文:macOS安装Scrapy,不要踩坑了

以下的踩坑经验,仅作参考,谨慎使用,只对CSDN上的常见操作做了汇总。

本机环境:MacOS 12.0+,Python3.8,Scrapy 2.6.1

以下是运行一个Scrapy的简单例子,在命令行输入scrapy runspider quotes_spider.py -o quotes.jl

import scrapy


class QuotesSpider(scrapy.Spider):
    name = 'quotes'
    start_urls = [
        'https://quotes.toscrape.com/tag/humor/',
    ]

    def parse(self, response):
        for quote in response.css('div.quote'):
            yield {
                'author': quote.xpath('span/small/text()').get(),
                'text': quote.css('span.text::text').get(),
            }

        next_page = response.css('li.next a::attr("href")').get()
        if next_page is not None:
            yield response.follow(next_page, self.parse)


最后运行成功,会生成一个quotes.jl文件,里面的内容应如下所示:

{"author": "Jane Austen", "text": "\u201cThe person, be it gentleman or lady, who has not pleasure in a good novel, must be intolerably stupid.\u201d"}
{"author": "Steve Martin", "text": "\u201cA day without sunshine is like, you know, night.\u201d"}
{"author": "Garrison Keillor", "text": "\u201cAnyone who thinks sitting in church can make you a Christian must also think that sitting in a garage can make you a car.\u201d"}
...

但是最后出现了报错:

MemoryError: Cannot allocate write+execute memory for ffi.callback(). You might be running on a system that prevents this. For more information, see https://cffi.readthedocs.io/en/latest/using.html#callbacks
2022-03-28 15:57:37 [scrapy.core.engine] INFO: Closing spider (finished)

根据网上资料,有以下几种方法。

方法1:删除pyopenssl库,安装openssl。

问题伴随SSL认证失败,经查资料:根据https://github.com/pyca/pyopenssl/issues/873,初步确定是pyopenssl,openssl有写和执行权限,而pyopenssl则没有。但是Scrapy依赖pyopenssl。

查看所在环境下是否存在pyopenssl,通过 pip show pyopenssl发现是存在的。如果执行删除conda uninstall pyopenssl,安装openssl,结果不可行。

方法2:更新requests库。

根据Stack上关于Scrapy在M1 Mac上的回复,尝试更新requests,pip3 install --upgrade requests。先更新conda,conda update conda,再更新requests。我的requests是2.27.1已经是当前最新的。最后还是不可行。

方法3:将python版本升级为3.10.4,然后重新安装scrapy

创建了一个Python=3.10的虚拟环境py310,重新安装scrapy,运行scrapy runspider quotes_spider.py -o quotes.jl后,出现了这个问题:Library not loaded: @rpath/libssl.1.1.dylib.

ImportError: dlopen(/Users/dan/miniforge3/envs/py310/lib/python3.10/site-packages/cryptography/hazmat/bindings/_openssl.abi3.so, 0x0002): Library not loaded: @rpath/libssl.1.1.dylib

Referenced from: /Users/dan/miniforge3/envs/py310/lib/python3.10/site-packages/cryptography/hazmat/bindings/_openssl.abi3.so
Reason: tried: '/Users/dan/miniforge3/envs/py310/lib/libssl.1.1.dylib' (no such file), '/Users/dan/miniforge3/envs/py310/lib/libssl.1.1.dylib' (no such file), '/Users/dan/miniforge3/envs/py310/lib/python3.10/site-packages/cryptography/hazmat/bindings/../../../../../libssl.1.1.dylib' (no such file), '/Users/dan/miniforge3/envs/py310/lib/libssl.1.1.dylib' (no such file), '/Users/dan/miniforge3/envs/py310/lib/libssl.1.1.dylib' (no such file), '/Users/dan/miniforge3/envs/py310/lib/python3.10/site-packages/cryptography/hazmat/bindings/../../../../../libssl.1.1.dylib' (no such file), '/Users/dan/miniforge3/envs/py310/bin/../lib/libssl.1.1.dylib' (no such file), '/Users/dan/miniforge3/envs/py310/bin/../lib/libssl.1.1.dylib' (no such file), '/usr/local/lib/libssl.1.1.dylib' (no such file), '/usr/lib/libssl.1.1.dylib' (no such file)

参考 Library not loaded: libcrypto.1.0.0.dylib issue in mac可以看到:

错误原因:

  1. Homebrew默认安装的openssl为1.0版本;最新的scrapy要求使用1.1版本
  2. 动态链接库路径有问题

解决方法:

Step 1. 使用brew安装openssl.

检查是否安装openssl:brew info openssl,发现并没有安装。使用brew安装brew install openssl

在这里插入图片描述

如果检查发现已安装了openssl 1.0,就更新到openssl 1.1,使用brew reinstall openssl@1.1,最后检查下openssl版本:brew info brew,记住你的openssl动态库文件libssl.1.1.dylib所在的地址:/opt/homebrew/Cellar/openssl@1.1/1.1.1k/lib/libssl.1.1.dylib

在这里插入图片描述

Step 2. 复制动态库文件libssl.1.1.dylib到路径@rpath中。

首先,定位到你的动态库文件所在地址:cd /opt/homebrew/Cellar/openssl@1.1/1.1.1k/lib;

在这里插入图片描述

然后,复制动态库文件libssl.1.1.dyliblibcrypto.1.1.dylib到路径@rpath中,如最开始报错提示的一些路径中,如’/Users/dan/miniforge3/envs/py310/lib/libssl.1.1.dylib’ (no such file),‘/usr/lib/libssl.1.1.dylib’(no such file)。

这里,将动态库文件添加到/Users/dan/miniforge3/envs/py310/lib/中:

sudo cp /opt/homebrew/Cellar/openssl@1.1/1.1.1k/lib/libssl.1.1.dylib /Users/dan/miniforge3/envs/py310/lib/
sudo cp /opt/homebrew/Cellar/openssl@1.1/1.1.1k/lib/libcrypto.1.1.dylib /Users/dan/miniforge3/envs/py310/lib/

异常:Operation not permitted

需要注意的是,如果是复制到/usr/lib/下,见如下命令,可能会出现Operation not permitted的权限问题情况:

这是因为电脑启用了SIP(System Integrity Protection),加入了Rootless机制,导致即使在root权限下依然无法修改文件。主要是因为Rootless机制是对抗恶意程序的最后防线。

解决方法1:如果即使在 sudo 之后您也收到权限被拒绝错误。尝试手动复制到 /usr/lib
  1. 打开Finder,使用command+shift+G,在弹出的目录中填写/opt/homebrew/Cellar/openssl@1.1/1.1.1k/lib,进入该目录,找到文件libssl.1.1.dylib进行复制:command + C;

  2. 使用command+shift+G,在弹出的目录中填写/usr/lib,进入该目录,粘贴文件libssl.1.1.dylib:command + V;

  3. 同上,复制libcrypto.1.1.dylib/usr/lib

解决办法2:在必要时候为了能够修改文件,只能关闭该保护机制。【不推荐】

1)重启,过程中按住 command+R,进入恢复分区. 然后找到 Terminal启动运行.

2)打开Terminal终端,输入csrutil disable

3)再次重启,即可对 usr/lib 目录下文件进行修改。

4)恢复保护机制,重新进入保护模式,输入 csrutil enable

sudo cp /opt/homebrew/Cellar/openssl@1.1/1.1.1k/lib/libssl.1.1.dylib /usr/lib/
sudo cp /opt/homebrew/Cellar/openssl@1.1/1.1.1k/lib/libcrypto.1.1.dylib /usr/lib/

或者

 ln -s /opt/homebrew/Cellar/openssl@1.1/1.1.1k/lib/libssl.1.1.dylib /usr/lib/
 ln -s /opt/homebrew/Cellar/openssl@1.1/1.1.1k/lib/libcrypto.1.1.dylib /usr/lib/

总结所有的操作:

	brew reinstall openssl@1.1  #下载1.1版本
	cd /opt/homebrew/Cellar     # 地址根据你的库文件定位
	# 如果没有安装openssl可忽略后两步
	mv openssl openssl@1.0 #重命名之前的版本
	mv openssl@1.1 openssl # 使用1.1
	# 定位到openssl库所在
	cd /opt/homebrew/Cellar/openssl@1.1/1.1.1k/lib
	sudo cp libssl.1.1.dylib libcrypto.1.1.dylib /usr/lib/
	# 接下来三步似乎不是必须的
	sudo rm libssl.dylib libcrypto.dylib
	sudo ln -s libssl.1.1.dylib libssl.dylib
	sudo ln -s libcrypto.1.1.dylib libcrypto.dylib

欢迎各位关注我的个人公众号:HsuDan,我将分享更多自己的学习心得、避坑总结、面试经验、AI最新技术资讯。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值