Scrapy 是一个十分强大的爬虫框架,依赖的库比较多,至少需要依赖的库有 Twisted 14.0、lxml 3.4 和 pyOpenSSL 0.14。在不同的平台环境下,它所依赖的库也各不相同,所以在安装之前,最好确保把一些基本库安装好。本节就来介绍 Scrapy 在不同平台的安装方法。
1. 相关链接
- 官方网站:https://scrapy.org
- 官方文档:https://docs.scrapy.org
- PyPI:https://pypi.python.org/pypi/Scrapy
- GitHub:https://github.com/scrapy/scrapy
- 中文文档:http://scrapy-chs.readthedocs.io
2. Anaconda 安装
这是一种比较简单的安装 Scrapy 的方法(尤其是对于 Windows 来说),如果你的 Python 是使用 Anaconda 安装的,或者还没有安装 Python 的话,可以使用此方法安装,这种方法简单、省力。当然,如果你的 Python 不是通过 Anaconda 安装的,可以继续看后面的内容。
关于 Anaconda 的安装方式,可以查看 1.1 节,在此不再赘述。
如果已经安装好了 Anaconda,那么可以通过conda命令安装 Scrapy,具体如下:
1 |
conda install Scrapy |
3. Windows 下的安装
如果你的 Python 不是使用 Anaconda 安装的,可以参考如下方式来一步步安装 Scrapy。
安装 lxml
lxml 的安装过程请参见 1.3.1 节,在此不再赘述,此库非常重要,请一定要安装成功。
安装 pyOpenSSL
在官方网站下载 wheel 文件(详见https://pypi.python.org/pypi/pyOpenSSL#downloads)即可,如图 1-76 所示。
图 1-76 下载页面
下载后利用 pip 安装即可:
1 |
pip3 install pyOpenSSL-17.2.0-py2.py3-none-any.whl |
安装 Twisted
到http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted下载 wheel 文件,利用 pip 安装即可。
比如,对于 Python 3.6 版本、Windows 64 位系统,则当前最新版本为 Twisted‑17.5.0‑cp36‑cp36m‑win_amd64.whl,直接下载即可,如图 1-77 所示。
图 1-77 下载页面
然后通过 pip 安装:
1 |
pip3 install Twisted‑17.5.0‑cp36‑cp36m‑win_amd64.whl |
安装 PyWin32
从官方网站下载对应版本的安装包即可,链接为:https://sourceforge.net/projects/pywin32/files/pywin32/Build%20221/,如图 1-78 所示。
图 1-78 下载列表
比如对于 Python 3.6 版本,可以选择下载 pywin32-221.win-amd64-py3.6.exe,下载完毕之后双击安装即可。
注意,这里使用的是 Build 221 版本,随着时间推移,版本肯定会继续更新,最新的版本可以查看https://sourceforge.net/projects/pywin32/files/pywin32/,到时查找最新的版本安装即可。
安装 Scrapy
安装好了以上的依赖库后,安装 Scrapy 就非常简单了,这里依然使用 pip,命令如下:
1 |
pip3 install Scrapy |
等待命令结束,如果没有报错,就证明 Scrapy 已经安装好了。
4. Linux 下的安装
在 Linux 下的安装方式依然分为两类平台来介绍。
CentOS 和 Red Hat
在 CentOS 和 Red Hat 下,首先确保一些依赖库已经安装,运行如下命令:
1 |
sudo yum groupinstall -y development tools |
最后利用 pip 安装 Scrapy 即可:
1 |
pip3 install Scrapy |
Ubuntu、Debian 和 Deepin
在 Ubuntu、Debian 和 Deepin 平台下,首先确保一些依赖库已经安装,运行如下命令:
1 |
sudo apt-get install build-essential python3-dev libssl-dev libffi-dev libxml2 libxml2-dev libxslt1-dev zlib1g-dev |
然后利用 pip 安装 Scrapy 即可:
1 |
pip3 install Scrapy |
运行完毕后,就完成 Scrapy 的安装了。
5. Mac 下的安装
在 Mac 下,首先也是进行依赖库的安装。
在 Mac 上构建 Scrapy 的依赖库需要 C 编译器以及开发头文件,它一般由 Xcode 提供,具体命令如下:
1 |
xcode-select --install |
随后利用 pip 安装 Scrapy 即可:
1 |
pip3 install Scrapy |
6. 验证安装
安装之后,在命令行下输入scrapy,如果出现类似如图 1-79 所示的结果,就证明 Scrapy 安装成功了。
图 1-79 验证安装
7. 常见错误
在安装过程中,常见的错误汇总如下。
pkg_resources.VersionConflict: (six 1.5.2 (/usr/lib/python3/dist-packages), Requirement.parse('six>=1.6.0'))
这是 six 包版本过低出现的错误。six 包是一个提供兼容 Python 2 和 Python 3 的库,这时升级 six 包即可:
1 |
sudo pip3 install -U six |
c/_cffi_backend.c:15:17: fatal error: ffi.h: No such file or directory
这是在 Linux 下常出现的错误,缺少 libffi 库造成的。什么是 libffi?FFI 的全名是 Foreign Function Interface,通常指的是允许以一种语言编写的代码调用另一种语言的代码。而 libffi 库只提供了最底层的、与架构相关的、完整的 FFI。此时安装相应的库即可。
在 Ubuntu 和 Debian 下,直接执行如下命令即可:
1 |
sudo apt-get install build-essential libssl-dev libffi-dev python3-dev |
在 CentOS 和 Red Hat 下,直接执行如下命令即可:
1 |
sudo yum install gcc libffi-devel python-devel openssl-devel |
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build/cryptography/
这是缺少加密的相关组件,此时利用 pip 安装即可:
1 |
pip3 install cryptography |
ImportError: No module named 'packaging'
这是因为缺少 packaging 包出现的错误,这个包提供了 Python 包的核心功能,此时利用 pip 安装即可。
ImportError: No module named '_cffi_backend'
这个错误表示缺少 cffi 包,直接使用 pip 安装即可:
1 |
pip3 install cffi |
ImportError: No module named 'pyparsing'
这个错误表示缺少 pyparsing 包,直接使用 pip 安装即可:
1 |
pip3 install pyparsing appdirs |




图 1-74 控制台
图 1-75 管理页面
图 1-71 下载页面
图 1-72 运行页面
图 1-73 Android SDK 设置页面
图 1-59 下载页面
图 1-60 证书文件
图 1-61 证书导入向导
图 1-62 密码设置提示
图 1-63 选择证书存储区域
图 1-64 安全警告
图 1-65 证书配置
图 1-66 证书安装页面
图 1-67 安装警告页面
图 1-68 安装成功页面
图 1-69 证书信任设置
图 1-70 证书安装页面
图 1-43 Charles 下载页面
图 1-44 证书安装页面入口
图 1-45 证书安装页面
图 1-46 证书导入向导
图 1-47 选择证书存储区域
图 1-48 证书配置
图 1-49 代理设置
图 1-50 代理设置
图 1-51 提示窗口
图 1-52 证书安装页面入口
图 1-53 提示窗口
图 1-54 证书安装页面
图 1-55 安装成功页面
图 1-56 证书信任设置
图 1-57 代理设置
图 1-58 证书安装页面
图 1-42 运行结果
图 1-41 运行结果
图 1-39 下载页面
图 1-40 系统服务页面
图 1-29 MongoDB 官网
图 1-30 指定安装路径
图 1-31 新建 data 目录
图 1-32 新建 db 目录
图 1-33 运行结果
图 1-34 以管理员身份运行
图 1-35 新建 mongodb.log 文件
图 1-36 运行结果
图 1-37 系统服务页面
图 1-38 命令行模式
图 1-27 设置密码页面
图 1-28 系统服务页面
图 1-23 验证码
图 1-24 下载页面
图 1-25 安装页面
图 1-26 测试样例
图 1-18 GeckoDriver 下载页面






接下来按照大才的文章,pip install gerapy 即可,这一步没有遇到什么问题。有问题的同学可以向大才提 issue。
然后到命令窗口对 8000 和 6800 端口放行即可。 接着执行
里面的各个的含义见大才的文章。
后来找了一下原因发现 scrapyd 默认打开的也是 127.0.0.1
所以这个时候就要改一下配置,具体可以参考

可以看到输出的结果了。
如图所示为 Bi-LSTM 的基本原理,输入层的数据会经过向前和向后两个方向推算,最后输出的隐含状态再进行 concat,再作为下一层的输入,原理其实和 LSTM 是类似的,就是多了双向计算和 concat 过程。
接下来我们在浏览器中打开
这里显示了主机、项目的状态,当然由于我们没有添加主机,所以所有的数目都是 0。 如果我们可以正常访问这个页面,那就证明 Gerapy 初始化都成功了。
需要添加 IP、端口,以及名称,点击创建即可完成添加,点击返回即可看到当前添加的 Scrapyd 服务列表,样例如下所示:
这样我们可以在状态一栏看到各个 Scrapyd 服务是否可用,同时可以一目了然当前所有 Scrapyd 服务列表,另外我们还可以自由地进行编辑和删除。
假设现在我们有一个 Scrapy 项目,如果我们想要进行管理和部署,还记得初始化过程中提到的 projects 文件夹吗?这时我们只需要将项目拖动到刚才 gerapy 运行目录的 projects 文件夹下,例如我这里写好了一个 Scrapy 项目,名字叫做 zhihusite,这时把它拖动到 projects 文件夹下:
这时刷新页面,我们便可以看到 Gerapy 检测到了这个项目,同时它是不可配置、没有打包的:
这时我们可以点击部署按钮进行打包和部署,在右下角我们可以输入打包时的描述信息,类似于 Git 的 commit 信息,然后点击打包按钮,即可发现 Gerapy 会提示打包成功,同时在左侧显示打包的结果和打包名称:
打包成功之后,我们便可以进行部署了,我们可以选择需要部署的主机,点击后方的部署按钮进行部署,同时也可以批量选择主机进行部署,示例如下:
可以发现此方法相比 Scrapyd-Client 的命令行式部署,简直不能方便更多。
我们可以通过点击新任务、停止等按钮来实现任务的启动和停止等操作,同时也可以通过展开任务条目查看日志详情:
另外我们还可以随时点击停止按钮来取消 Scrapy 任务的运行。 这样我们就可以在此页面方便地管理每个 Scrapyd 服务上的 每个 Scrapy 项目的运行了。
这样即使 Gerapy 部署在远程的服务器上,我们不方便用 IDE 打开,也不喜欢用 Vim 等编辑软件,我们可以借助于本功能方便地完成代码的编写。
再比如爬取规则,我们可以指定从哪个链接开始爬取,允许爬取的域名是什么,该链接提取哪些跟进的链接,用什么解析方法来处理等等配置。通过这些配置,我们可以完成爬取规则的设置。
最后点击生成按钮即可完成代码的生成。
生成的代码示例结果如图所示,可见其结构和 Scrapy 代码是完全一致的。
生成代码之后,我们只需要像上述流程一样,把项目进行部署、启动就好了,不需要我们写任何一行代码,即可完成爬虫的编写、部署、控制、监测。
在上图网络结构中,对于矩形块 A 的那部分,通过输入xt(t时刻的特征向量),它会输出一个结果ht(t时刻的状态或者输出)。网络中的循环结构使得某个时刻的状态能够传到下一个时刻。 这些循环的结构让 RNNs 看起来有些难以理解,但我们可以把 RNNs 看成是一个普通的网络做了多次复制后叠加在一起组成的,每一网络会把它的输出传递到下一个网络中。我们可以把 RNNs 在时间步上进行展开,就得到下图这样:
所以最基本的 RNN Cell 输入就是 xt,它还会输出一个隐含内容传递到下一个 Cell,同时还会生成一个结果 ht,其最基本的结构如如下:
仅仅是输入的 xt 和隐藏状态进行 concat,然后经过线性变换后经过一个 tanh 激活函数便输出了,另外隐含内容和输出结果是相同的内容。 我们来分析一下 TensorFlow 里面 RNN Cell 的实现。 TensorFlow 实现 RNN Cell 的位置在 python/ops/rnncellimpl.py,首先其实现了一个 RNNCell 类,继承了 Layer 类,其内部有三个比较重要的方法,state_size()、output_size()、__call() 方法,其中 state_size() 和 output_size() 方法设置为类属性,可以当做属性来调用,实现如下:
但是如果我们想依赖前文距离非常远的信息时,普通的 RNN 就非常难以做到了,随着间隔信息的增大,RNN 难以对其做关联:
但是 LSTM 可以用来解决这个问题。 LSTM,Long Short Term Memory Networks,是 RNN 的一个变种,经试验它可以用来解决更多问题,并取得了非常好的效果。 LSTM Cell 的结构如下:
LSTMs 最关键的地方在于 Cell 的状态 和 结构图上面的那条横穿的水平线。 Cell 状态的传输就像一条传送带,向量从整个 Cell 中穿过,只是做了少量的线性操作。这种结构能够很轻松地实现信息从整个 Cell 中穿过而不做改变。
若只有上面的那条水平线是没办法实现添加或者删除信息的,信息的操作是是通过一种叫做门的结构来实现的。 这里我们可以把门分为三个:遗忘门(Forget Gate)、传入门(Input Gate)、输出门(Output Gate)。
在经过 Forget Gate 和 Input Gate 处理后,我们就可以对输入的 Ct-1 做更新了,即把Ct−1 更新为 Ct,首先我们把旧的状态 Ct−1 和 ft 相乘, 把一些不想保留的信息忘掉。然后加上 it∗Ct~,这部分信息就是我们要添加的新内容,这样就可以完成对 Ct-1 的更新。 
到了最后,其输出结果有三个内容,其中输出结果就是最上面的箭头代指的内容,即最终计算的结果,隐层包括两部分内容,一个是 Ct,一个是最下方的 ht,我们可以将其合并为一个变量来表示。 接下来我们来看下 LSTMCell 的 TensorFlow 代码实现。 首先它的类是 BasicLSTMCell 类,继承了 RNNCell 类,其初始化方法 init() 实现如下:
另外还有一个变种就是将 Forget Gate 和 Input Gate 二者联合起来,做到要么遗忘老的输入新的,要么保留老的不输入新的。
但接下来还有一个更常用的变种,俺就是 GRU,它是由 Cho, et al. (2014) 提出的,在提出的同时他还提出了 Seq2Seq 模型,为 Generation Model 做好了铺垫。
接下来我们看下 TensorFlow 中 GRUCell 的实现,代码如下: