基于 Scrapy 的分布式爬虫设计与实现(以知乎为例)

本贴最后更新于 1970 天前,其中的信息可能已经时移世易

1. 背景

网络爬虫是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。早期的爬虫被用于搜索引擎,不过随着大数据概念的兴起。越来越多人使用爬虫作为获取数据的一种手段、以此来训练模型实现某些功能。基于此,我们也实现了一个爬虫,并在分布式集群化部署上做出了一些自己的尝试。

在语言的选择上,在项目开始的时候曾考虑了 C++、Python 和 JAVA。其中 Python 相关库较多,和 JAVA、C++ 相比 Python 在小型项目开发上具有一些优势,因此最后决定使用 Python 作为项目的开发语言。

在开发代码的过程中,我们进行了简单的功能实现。但是在调试的过程中,我们发现网页抓取效率比较低。因此我们额外进行了模块解耦,在经过两次模块解耦后,网页抓取效率有了一个较为明显的提升,满足投入生产环境的需要。

经过 3 小时三台服务器的抓取,一共获得 2246647 名知乎用户信息。在获得用户信息后,我们使用 SQL 做一个简单的数据用户分析并刻画知乎用户画像。并得出结论:知乎是以互联网行业用户为主体、男性用户居多、马太效应比较严重的社区。

囿于爬虫的效率(主要原因是只有一个知乎帐号)和时间限制(租用服务器也是一笔开销),获得的样本数目不是很多,结论未必正确。不过在爬虫分布式的尝试是值得的。本项目已经支持多帐号 Cookie 池。倘若能提供知乎帐号,效率一定会有更大的提升。

最后,整个项目代码保存在 https://github.com/woooosz/zhihuSpider

2.系统的战略分析

2.1 现状分析

最早的爬虫起源于搜索引擎。与其他恶意收集数据的爬虫相比,搜索引擎是“善意”的爬虫,可以检索你的一切信息,并提供给其他用户访问。为此他们还专门定义了 robots.txt 文件,作为君子协定,这是一个双赢的局面。

然而,随着“大数据”等概念的流行,越来越多的人开始研究爬虫。这些有害流量目标网站带来了巨大的影响(例如比价网站、服务器带宽支出等),因此现在越来越多的网站开始使用反爬虫措施。对于目前爬虫的现状,我将会从以下两点进行分析:

2.1.1 语言

理论上来说,任何支持网络通信的语言都是可以写爬虫的,爬虫本身虽然语言关系不大,和语言规范相比、语言背后所蕴含的编程思想更加重要,但是,总有相对顺手、简单的。目前来说,大多数爬虫是用后台脚本类语言写的,其中 python 无疑是用的最多最广的,并且页诞生了很多优秀的库和框架,如 scrapy、BeautifulSoup 、pyquery、Mechanize 等。但是一般来说,搜索引擎的爬虫对爬虫的效率要求更高,会选用 c++、java、go。

但是发现和 python 实现的爬虫效率提升并不明显,原因是,对于简单爬虫,瓶颈在于数据分析及提取,而网络效率和语言关系并不大。值得一提的是,在近几年 node 发展非常快,使得 javascript 遍地开花,有些人也开始尝试用 node 做爬虫,但是,这其实和其它后台脚本语言没什么区别,也不如 python 简单,因为你依旧不能在 node 里发起 ajax 请求,不能执行原网页的 dom。因为 node 的 javascript 执行环境和浏览器的执行环境并不相同。那么,难道就真的不能像在浏览器中一样用 js 写爬虫,用 jquery 提取内容吗?这个想法从理论上是可行的,不过目前还没有相关的项目出现。

2.2.2 运行环境

爬虫本身不区分到底是运行在 windows 还是 Linux,又或是 OSX,但从业务角度讲,我们把运行在服务端(后台)的,称之为后台爬虫。而现在,几乎所有的爬虫都是后台爬虫。

后台爬虫在大行其道的时候,也有着些许棘手的、到目前也没有什么好的解决方案问题,而归根结底,这些问题的根本原因是由于后台爬虫的先天不足导致。后台爬虫与浏览器的相同点在于他们本质上都是通过 http/https 协议请求互联网数据。不同点在于爬虫一般为自动化程序,无需用用户交互,而浏览器不是。运行场景不同;浏览器运行在客户端,而爬虫一般都跑在服务端。能力不同;浏览器包含渲染引擎、javascript 虚拟机,而爬虫一般都不具备这两者。

2.2 存在问题

尽管当前的知乎爬虫项目很多,我在设计分布式爬虫系统之前也阅读了不少其他开发者编写的爬虫代码,不过随着知乎反爬虫技术的提高。目前这些爬虫普遍存在的问题有:

2.2.1. 验证码问题

知乎在 2017 年 8 月份更新了用户登录时验证码的验证规则,由原来的图片字母式验证码改为了选取图中的倒立字。其验证逻辑是提交倒立字所在的二维坐标,由服务器验证提交的坐标是否处于合理阈值范围内。这一变化使得目前 70% 的知乎爬虫项目无法正常运行。

本项目采用知乎最新的二维码登录方式,通过抓包详细分析服务端与浏览器之间的交互逻辑、模拟登录申请 token,生成二维码。对于用户来说,只需要打开的知乎客户端上面的扫一扫功能扫码二维码就能够完成登录。与其他项目开发者要求用户自行将 cookie 中的某些字段写入数据库中来说,本项目对用户友好。

2.2.2. 爬虫的拓展性有待提高

目前网上的爬虫项目大多是基于 Scrapy 单机爬虫项目,其存放 request 的队列实现本质仍然是 python 自带的 Collection.deque。无法满足分布式、集群化的要求,本项目使用 Scrapy-redis 组建替代 Scrapy 的 Scheduler。将存放 request 的队列替换为 Redis,这样做的好处是,多个爬虫可以共享一个 Request 队列,能够使得多个爬虫协同工作。满足集群式、分布式的要求。

本项目使用 Scrapy-redis 的同时,自行设计若干 Redis 辅助队列,满足项目的实际业务逻辑需要。

2.2.3. 部分爬虫项目反反爬虫的措施应对不足

随着越来越多开源爬虫项目的发布与数据挖掘的发展,越来越多人投入到爬虫的学习中,然而很多人技术不够成熟。不加限制地在自己的服务器或电脑上运行现成的爬虫代码。给目标网站带来了巨大的垃圾流量,造成的业务的瘫痪(参考 17.9 煎蛋网爬虫事件)

这直接促使了越来越多公司使用更高水平的反爬虫措施。对于知乎、今日头条一类的内容创作型网站来说,其网站的反爬虫策略比其他类型的网站反爬虫策略更为严格。这些网站从 cookie、user-agent 等方面入手,对流量分析识别,限制爬虫用户。

这是目前对后台爬虫中最致命的。网站的防火墙会对某个固定 IP 在某段时间内请求的次数做限制,如果没有超过上线则正常返回数据,超过了,则拒绝请求,如 QQ 邮箱。

值得说明的是,IP 限制有时并非是专门为了针对爬虫的,而大多数时候是出于网站安全原因针对 DOS 攻击的防御措施。后台爬取时机器和 IP 有限,很容易达到上线而导致请求被拒绝。目前主要的应对方案是使用代理,这样一来 IP 的数量就会多一些,但代理 IP 依然有限,对于这个问题,根本不可能彻底解决。

常言道:“爬虫的关键之处就在于模拟浏览器的行为”,本项目重写 downloader 中间件,构建 Cookie 池、user-agent 池,http-proxy 池。在每次请求服务器前,随机选择 Cookie、User-agent 和 IP。满足了在分布式、大规模爬虫项目下目标网站对爬虫的限制。

2.2.4. Javascript 解析问题

javascript 可以动态生成 dom。目前大多数网页属于动态网页(内容由 javascript 动态填充),尤其是在移动端,SPA/PWA 应用越来越流行,网页中大多数有用的数据都是通过 ajax/fetch 动态获取后然后再由 js 填充到网页 dom 树中,单纯的 html 静态页面中有用的数据很少。

目前主要应对的方案就是对于 js ajax/fetch 请求直接请求 ajax/fetch 的 url ,但是还有一些 ajax 的请求参数会依赖一段 javascript 动态生成,比如一个请求签名,再比如用户登陆时对密码的加密等等,如果一昧的去用后台脚本去干 javascript 本来做的事,这就要清楚的理解原网页代码逻辑,而这不仅非常麻烦,而且会使你的爬取代码异常庞大臃肿。

但是,更致命的是,有些 javascript 可以做的事爬虫程序是很难甚至是不能模仿的,比如有些网站使用拖动滑块到某个位置的验证码机制,这就很难再爬虫中去模仿。

其实,总结一些,这些弊端归根结底,是因为爬虫程序并非是浏览器,没有 javascript 解析引擎所致。针对这个问题,目前主要的应对策略就是在爬虫中引入 Javascript 引擎,如 PhantomJS,但是又有着明显的弊端,如服务器同时有多个爬取任务时,资源占用太大。

还有就是,这些无窗口的 javascript 引擎很多时候使用起来并不能像在浏览器环境中一样,页面内部发生跳转时,会导致流程很难控制。

2.3 系统拟实现功能

分布式爬虫作为一个信息收集系统,可用性是其重中之重。因此从系统可用性出发拟实现一下功能:

  1. 获得 Cookie,构建 Cookie 池。为抓取信息做准备。

  2. 设计分布式多爬虫架构,设计 Redis 队列。

  3. 一些必要的反反爬虫措施。

  4. 一些数据库操作,将数据存储到数据库中。

3.系统需求分析

3.1 需求获取实施方案

对于这个项目的需求获取,主要使用虚拟用户构想法。将自己化身为用户,思考用户使用场景。首先项目的定位是有一定计算机基础、对数据爬取速度有一定要求的客户。主要的工作就是通过分布式的方式帮助用户完成数据获取。

3.2 需求分析

3.2.1 Scrapy 分析

Scrpay 是一个较好的开源爬虫框架,其主要由一下 5 个模块功能构成:

(1) 最重要的模块是 Engine:它是数据流的指挥官,负责控制数据流(控制各个模块之间的通信);

(2) scheduler:负责将 Engine 提交的 URL 排成一个队列;

(3) spider:用户自己写的代码放在 spider。主要负责 HTTP response 的解析,从回复的 HTML 中提取关键数据。

(4) downloader:负责跟 URL 对应的 server 通信,并获取返回的内容。

(5) item pipeline:负责处理 spider 提取出来的信息,一般用于做跟 DB 相关的操作。

中间件的目的主要是提供一种简易的机制,通过插拔用户自己写的代码,来扩展新功能。

典型的数据流如一下步骤所示:

(1) Engine 启动,从 spider 中读出要爬的第一个 URL

(2) Engine 将读到的第一个 URL 送给 scheduler

(3) Engine 向 scheduler 请求下一个要爬的 URL

(4) scheduler 从队列中读出一个 URL,送给 Engine,Engine 将这个 URL 送到 downloader

(5) downloader 去 GET 这个 URL,并将 HTTP response 生成一个 Response 对象。downloader 将生成的 Response 返回给 Engine

(6) Engine 将这个 Response 对象发给 spider

(7) spider 处理这个 Response 对象,提取其中的信息,生成 item。还会生成新的请求。并将 item 和请求送给 Engine

(8) Engine 将收到的请求送给 scheduler,将收到的 item 送给 item pipline

(9) 重复步骤(2),直到没有 URL 需要继续处理

这样的架构设计好处主要有以下几点:
(1) 模块划分清晰,各模块之间无功能重叠,各模块合起来也能表示常用的爬虫功能
(2) 功能可通过中间件进行扩展
(3) scheduler 可设置调度策略,并发爬多个 URL
(4) 各模块之间不能独立通信,必须由 Engine 控制,不会出现混乱
(5) Pipeline 模块只处理爬到的关键信息(item),不用处理不关注的大量 HTML 数据
(6) 用户只需要关注 HTTP response 的解析,从回复的 HTML 中提取关键数据

因此用 scrapy 框架完成爬虫的操作是完全可行的。

3.2.2 Scrapy-Redis 分析

我对 scrapy-redis 的理解就是 scrapy-redis 巧妙的利用 redis 的 list 实现 request 的 job queue 和 items queue,利用 redis 的 set 实现 request 的去重,将 scrapy 从单台机器扩展多台机器,实现较大规模的爬虫集群。

scrapy 原生的任务调度是基于文件系统,通过 JOBDIR 指定任务信息存储的路径。这样只能在单机执行 crawl。scrapy-redis 将任务和数据信息的存取放到 redis queue 里,使多台服务器可以同时执行 crawl 和 tems process,大大提高了数据爬取和处理的效率。

scrapy-redis 是基于 redis 的 scrapy 组件,主要功能如下:

Scrapy Engine 引擎负责控制数据流在系统中所有组件中流动,并在相应动作发生时触发事件。

调度器从引擎接受 request 并将他们入队,以便之后引擎请求他们时提供给引擎。

Spider 是 Scrapy 用户编写用于分析 response 并提取 item 或额外跟进的 URL 的类,每个 spider 负责处理一个特定网站。

item pipeline 负责处理被 spider 提取出来的 item。典型的处理有清理、验证及持久化的功能。

Scrapy 中的数据流由执行引擎控制,其过程如下:

首先引擎打开一个网站,找到处理该网站的 Spider 并向该 spider 请求第一个要爬取的 URL。引擎从 Spider 中获取到第一个要爬取的 URL 并在调度器以 Request 调度。引擎向调度器请求下一个要爬取的 URL。调度器返回下一个要爬取的 URL 给引擎,引擎将 URL 通过下载中间件转发给下载器。一旦页面下载完毕,下载器生成一个该页面的 Response,并将其通过下载中间件发送给引擎。引擎从下载器中接收到 Response 并通过 Spider 中间件发送给 Spider 处理。Spider 处理 Response 并返回爬取到的 Item 及新的 Request 给引擎。最后引擎将(Spider 返回的)爬取到的 Item 给 Item Pipeline,将 Request 给调度器。重复直到调度器中没有更多地 request,引擎关闭该网站。

综上所述,使用 scrapy-redis 能够很好满足分布式的要求。

3.3 系统需求建模

4.系统设计

4.1 系统总体设计

4.4.1 爬虫架构设计

以三台计算机为例,系统架构设计如图所示。其中 Redis 为内存数据库。Mysql 为当前主流的数据库。具体的架构说明如下:

Slave 首先查看 url_token,并存储到 Redis 上。等待 Master 做进一步的处理。

Master 端则是处于忙等待状态,时刻遍历 request_ID(存储 slave 端遍历的 url_token)中的信息,通过知乎的 Api 获取该 url_token 对应的用户信息。并将信息通过 pipelines 存储到数据库中。

4.1.2 爬虫原理简述

传统爬虫从一个或若干初始网页的 URL 开始,获得初始网页上的 URL,在抓取网页的过程中,不断从当前页面上抽取新的 URL 放入队列,直到满足系统的一定停止条件。聚焦爬虫的工作流程较为复杂,需要根据一定的网页分析算法过滤与主题无关的链接,保留有用的链接并将其放入等待抓取的 URL 队列。然后,它将根据一定的搜索策略从队列中选择下一步要抓取的网页 URL,并重复上述过程,直到达到系统的某一条件时停止。另外,所有被爬虫抓取的网页将会被系统存贮,进行一定的分析、过滤,并建立索引,以便之后的查询和检索;所以一个完整的爬虫一般会包含如下三个模块:网络请求模块、爬取流程控制模块、内容分析提取模块。

爬虫其实就是一堆的 http(s)请求,找到待爬取的链接,然后发送一个请求包,得到一个返回包,当然,也有 HTTP 长连接(keep-alive)或 h5 中基于 stream 的 websocket 协议,这里暂不考虑,所以核心的几个要素就是:url、请求 header、body、响应 herder、内容。
URL

爬虫开始运行时需要一个初始 url,然后会根据爬取到的 html 文章,解析里面的链接,然后继续爬取,这就像一棵多叉树,从根节点开始,每走一步,就会产生新的节点。为了使爬虫能够结束,一般都会指定一个爬取深度(Depth)。
Http 请求

http 请求信息由请求方法(method)、请求头(headers)、请求正文(body)三部分组成。由于 method 一般是 header 中的第一行,也可以说请求头中包含请求方法。
对于爬虫需要注意的是请求方法是 post 时,需要将请求的参数先进行 urlencode 后再发送,后台收到请求信息后可能会做一些校验,这可能会影响到爬取。

所谓爬取流程,就是按照什么样的规则顺序去爬。在爬取任务不大的情况下,爬取的流程控制不会太麻烦,很多爬取框架都已经帮你做了如 scrapy,只需要自己实现解析的代码。但在爬取一些大型网站时,例如全网抓取京东的评论,微博所有人的信息,关注关系等等,这种上十亿到百亿次设置千亿次的请求必须考虑效率,否则一天只有 86400 秒,那么一秒钟要抓 100 次,一天也才 8640w 次请求,也需要 100 多天才能到达十亿级别的请求量。涉及到大规模的抓取,一定要有良好的爬虫设计,一般很多开源的爬虫框架也都是有限制的,因为中间涉及到很多其他的问题,例如数据结构,重复抓取过滤的问题,当然最重要的是要把带宽利用满,所以分布式抓取很重要,这时流程控制就会很重要,分布式最重要的就是多台机器不同线程的调度和配合,通常会共享一个 url 队列,然后各个线程通过消息通信,如果想要抓的越多越快,那么对中间的消息系统的吞吐量要求也越高。现在也有一些开源的分布式爬取框架如 scrapy-Redis 就是一个重写了 scrapy 的调度模块、队列、管道的包,redis数据库是用来在分布式中做请求队列共享,scrapyd 是用来部署 scrapy 的,scrapyd-api 用来启动获取数据。

请求 headers 的 Accept-Encoding 字段表示浏览器告诉服务器自己支持的压缩算法(目前最多的是 gzip),如果服务器开启了压缩,返回时会对响应体进行压缩,爬虫需要自己解压。

过去我们常需要获取的内容主要来源于网页 html 文档本身,也就是说,我们决定进行抓取的时候,都是 html 中包含的内容,但是随着这几年 web 技术飞速的发展,动态网页越来越多,尤其是移动端,大量的 SPA 应用,这些网站中大量的使用了 ajax 技术。我们在浏览器中看到的网页已不全是 html 文档说包含的,很多都是通过 javascript 动态生成的,一般来说,我们最终眼里看到的网页包括以下三种:

Html 文档本身包含内容是最容易解决的,一般来讲基本上是静态网页已经写死的内容,或者动态网页,采用模板渲染,浏览器获取到 HTML 的时候已经是包含所有的关键信息,所以直接在网页上看到的内容都可以通过特定的 HTML 标签得到。

一般来说有两种情况:一种情况是在请求到 html 文档时,网页的数据在 js 代码中,而并非在 html 标签中,之所以我们看到的网页是正常的,那是因为,其实是由于执行 js 代码动态添加到标签里面的,所以这个时候内容在 js 代码里面的,而 js 的执行是在浏览器端的操作,所以用程序去请求网页地址的时候,得到的 response 是网页代码和 js 的代码,所以自己在浏览器端能看到内容,解析时由于 js 未执行,肯定找到指定 HTML 标签下内容肯定为空,如百度的主页就是这种,这个时候的处理办法,一般来讲主要是要找到包含内容的 js 代码串,然后通过正则表达式获得相应的内容,而不是解析 HTML 标签。另一种情况是在和用户交互时,JavaScript 可能会动态生成一些 dom,如点击某个按钮弹了一个对话框等;对于这种情况,一般这些内容都是一些用户提示相关的内容,没什么价值,如果确实需要,可以分析一下 js 执行逻辑,但这样的情况很少。

Ajax/Fetch 异步请求现在是很常见的,尤其是在内容以分页形式显示在网页上,并且页面无刷新,或者是对网页进行某个交互操作后,得到内容。对于这种页面,分析的时候我们要跟踪所有的请求,观察数据到底是在哪一步加载进来的。然后当我们找到核心的异步请求的时候,就只需抓取这个异步请求就可以了,如果原始网页没有任何有用信息,也没必要去抓取原始网页。

4.2 系统软件系统设计

4.2.1 模拟登录

模拟登录的核心是模拟浏览器的行为,本部分将着重描述知乎模拟登录(https://zhihu.com/signin)交互过程。

首先服务器端在本地设置四个字段,_xsrf、aliyungf_tc、d_c0、q_c1,其中_xsrf 的作用是知乎防范跨域请求伪造而设置的字段,aliyungf_tc 从字面理解上面看,应该是阿里云防 ddos 而设置的字段。在模拟登录中,只有_xsrf 的字段是有用的字段。

浏览器访问 https://www.zhihu.com/api/v3/oauth/captcha?lang=cn 这个 api,其返回值为这个 api 的作用是知乎根据你的 ip、登录次数等行为对用户是否爬虫用户进行识别,倘若判断该用户为风险用户。则返回{"show_captcha":true},要求该用户输入验证码(这个验证码用模拟登录处理比较困难)。此外,还会服务器还会在设置 capsion_ticket 字段。这个字段也是一个很重要的,倘若拿不到这个字段,在请求二维码的 token 时,将会返回失败。

值得一提的是,在 header 部分,需要添加一个 authorization 字段,写入“oauth c3cef7c66a1843f8b3a9e6a1e3160e20”值,如果不设置这个字段,则会返回请求错误的消息。接下来遇到的问题是:这个字段一定不可能是凭产生的,既然如此,这个值又是如何产生的呢?从交互逻辑上看,应该是通过 ajax 产生的 Get 请求。可是 ajax 可以设置 headers 吗?经过我查阅资料,ajax 是的确可以设置 headers 的,经过进一步分析,找到了关于这个字段的信息。

既然知道了这个字段的来源,可以用这则表达式提取这段 md5 值,用于提交请求拿到 capsion_ticket。

接下来用之前请求获得的 cookie 请求 qrcode api,该 api 会返回一个 token 值,和一个过期时间戳。

之后用 https://www.zhihu.com/account/scan/login/rwXn1UAdSwWn0EwQ 网址生成二维码,等待用户扫码登录。

当用户成功扫码并确认登录后,需要再次请求以下 api,倘若服务器端成功确认用户扫码,则会在本地生成一个 d_c0 字段,至此模拟登录完成。访问知乎其他用户信息 api、查看答案都不会有限制,至此模拟登录结束。https://account.zhihu.com/api/login/qrcode/rwXn1UAdSwWn0EwQ/scan_info

4.2.2 request 队列

知乎用户的唯一标识是 url_token。在项目开始时,我认为设置一些用户的 url_token,爬虫会请求该用户的关注者 api,,获取关注者的 url_token。接下来获取关注者的关注者的 url_token,并将获取的 url_token 写入到 redis 服务器中。

API:https://www.zhihu.com/api/v4/members/simonzhang1/followers

4.2.3 内容抓取

对于内容的抓取,使用知乎的用户信息 api,对于数据内容的抓取。我们可以将数据转化成 json 格式再进行进一步的处理。

API:https://www.zhihu.com/api/v4/members/simonzhang

4.3 数据分析

经过 3 个小时的数据抓取,一共获得了 22467 名知乎用户信息。他们一共提出了 11618085 个问题,获得了 711408138 次赞同,获得了 402326069 次收藏,收获了 132669345 次感谢,出席了 356328 场知乎 Live。

4.3.1 知乎用户性别比例

从数据看,知乎男性占比较高有 116653 名,女性用户有 68514 名,此外还有 39480 名用户性别未知。

4.3.2 知乎用户行业分布

在从事行业上,互联网当之无愧成为了知乎社区行业分布中的佼佼者,此外高新科技、法律、信息传媒等行业也占据了知乎的半壁江山。

这种用户构成直接影响到知乎目前的内容分布(以下观点基于日常观察和合理推测)。
知乎目前的内容构成以互联网&IT 领域为主导,以大学生兴趣爱好及基础专业知识次之。互联网 it 行业由于知识领域很宽,且行业热度高,很容易引发出丰富的话题,由于人人都是该行业的用户,所以其内容的可参与度也很高。但也正因为其用户比例太高,很多优秀的专业人士都有积极的表现,无形中抬高了用户在这个领域参与内容贡献的门槛,除非你真的很优秀,你的回答才能引起足够的关注和赞同。

广告、传媒、咨询等专业服务行业本身并没有太多独立的内容。而且它们跟互联网&IT 的关联性也较高,很多互联网从业者的工作关联行业都是广告传媒和咨询服务,因此这几个领域的用户也有很多的内容参与表现。

传统行业的人群比例较低,因此一些传统行业背景的用户往往更容易引起关注。他们的知识相较知乎现有用户群体具有不对称性优势。

4.3.2 知乎用户就读高校分布

在学校上,知乎学校人数和学校综合实力是密切相关的:学校 top10-20:同济大学,中国人民大学,吉林大学,山东大学,电子科技大学,华南理工大学,厦门大学,哈尔滨工业大学,东南大学,中南大学。学校 top20-30:北京航天航空大学,北京邮电大学,南开大学,重庆大学,天津大学,中国传媒大学,郑州大学,西安电子科技大学,大连理工大学,武汉理工大学

4.3.2 知乎用户回答关注情况

有 184221 个人在注册过知乎后没有纂写一个问题。然而,写过答案的人里,还有一半从来没得到过赞同、三分之一左右没有人关注。

换言之,被别人点过哪怕一个赞同的用户,也已经在整个知乎排到了前 6% 内。这也就是说,在知乎,信息的创造仅仅是由其中的一小部分人来完成的,绝大多数的人仅仅是信息的接受者罢了。

5.系统的实施

5.1 系统开发组织

由于是我的个人项目,因此,项目代码编写、项目调试、项目 bug 的修复均由我一个人来完成。

5.2 系统发布实施流程

就本项目而言,开发环境是 mac OS。然而,在实际部署的过程中,需要将该项目部署到三台服务器上。服务器的操作系统是 Cent OS,为了方便代码之间的同步,我使用 github 来进行代码的维护。

当完成一个版本之后,在开发环境提交代码并 push 到 github 服务器上。

当需要同步代码时,需要远程登录到集群服务器上,使用 git pull 一条命令同步到生产服务器上。

由于生成环境中还有其他项目在运行,需要将不同项目的环境隔离开来。virtualenv 是一个创建隔绝的 Python 环境的工具。virtualenv 创建一个包含所有必要的可执行文件的文件夹,用来使用 Python 工程所需的包。

5.3 系统测试和运行维护

系统测试工作主要在开发环境来完成,主要的工作测试系统各个功能模块是否出现问题,对可能出现的问题进行处理。主要处理的模块有:模拟登录模块、二维码模块、request 队列构建模块、数据抓取模块。

运行和维护主要是通过 ssh 完成这里无需赘述。

  • Scrapy
    7 引用 • 12 回帖
  • Python

    Python 是一种面向对象、直译式电脑编程语言,具有近二十年的发展历史,成熟且稳定。它包含了一组完善而且容易理解的标准库,能够轻松完成很多常见的任务。它的语法简捷和清晰,尽量使用无异义的英语单词,与其它大多数程序设计语言使用大括号不一样,它使用缩进来定义语句块。

    536 引用 • 672 回帖
  • Redis

    Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。从 2010 年 3 月 15 日起,Redis 的开发工作由 VMware 主持。从 2013 年 5 月开始,Redis 的开发由 Pivotal 赞助。

    284 引用 • 247 回帖 • 174 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...