python 爬虫 入门 commit by commit -- commit8

"提高速度,减小资源使用,易于维护是软件开发不变的核心" -- by 我自己

代码你可以在https://github.com/rogerzhu/relwarcDJ 上得到,并且带有我完整的commit记录。

这个commit内容的运行并不会有什么惊喜的改变,但是如果你的机器想像我所使用的这台,10年前的thinkpad,双核,当年可是高端配置,你就能比较明显的发现速度上的提高。而且,与其说这一个commit是我在介绍我运用的python的功能,我觉得我很容易会写成为啥我喜欢在linux下开发程序的舔文。

我经常开玩笑说,如果做c++的,没有经历过两件事的话,不会知道这语言调试起来有多痛苦。一个是内存泄露,一个是多线程bug。这两种错误,需要你有极高的耐心,一些理论知识和越多越好的实践经验,最重要的是,有时候要有一点运气。不然,你会陷入到一种,我是改了,到底有没有改好的自我怀疑之中。

而现实中的情况是,为了提高速率,使用并发是一个理所当然的技术选择。而在windows上,系统的设计让你几乎只有多线程这一条路走,当然在c++中,feature,promise这些concurrency关键词的引入使得这方面有了更多的选择。而线程之间的同步很容易让你陷入到一个崩溃的境地。而linux,秉承着KISS(Keep it simple,stupid)的原则,讲究一个进程尽量设计成功能单一,性能稳定的小程序。而进程间的通信又是无比的方便,关键是,像windows系统所逼迫出来的大家长式的程序,一个线程挂了,很多时候整个进程就hang住了。而Linux在守护进程的管理下,一个进程挂了,只要再重新启动一下就好了。在我胡扯这些文章的时候,我的输入法崩溃过n次,但是我不需要担心,系统会自动帮我重新加载IME模块,而其余的部分完全可以继续一如既往的工作。

前面说了这么多,就是为了这里铺垫的,我想对我的爬虫程序的速度提高一点,毕竟,更快是每个程序员不屑,哦不,是不懈的追求。而python中对于编写并发有很多种方法,在linux上我毫不犹豫的选择多进程的方法。

python的多进程,在本质上就是调用了fork方法,作为linux的经典方法,fork是一个伟大而又特别的函数。接口简单,使用简单。特别的是调用一次,返回两次。当然,作为使用python语言本身,你完全可以对这个细节不做任何了解,依然不会对你使用python多进程有任何影响。

python对于多进程的支持也十分简单,首先调用Pool的构造函数构造出一个进程池(当然,这些函数所在的包,都可以在代码的开头找到)。然后使用apply_async函数,传入要执行的进程函数,后面依次都是参数,接着就是关闭进程和使用join等待所有进程结束。核心用法不过四行,你就可以创建多进程函数,相比传统C++,实在是方便了太多。这里我想扯一点题外话,在程序的164行,我使用的是range,而在python3中,引入了新的一个叫做xrange的东西。如果你足够严格,这个地方用xrange会更好。那么,他们有什么差别呢?一句话的话,range会一次性生成整个列表,而xrange只会一个一个生成你想要的。再简单点,xrange更节省资源。

那么剩下的就是看看CrawlTheItem到底是啥了。其实这个函数里面的内容在前面一直存在,就是前面的爬虫主体函数。当然,因为加了参数的原因,函数略有改动。但是,说白了,核心改动也就是这个地方:

这里可以写的更好,但是目前我就暂时图个方便。逻辑简单,因为第一页的url不同,所以,只能特殊情况特殊处理了。而对于后面的页码,采用,循环的方式再合适不过了,只不过,原先我们只要从第一页开始循环起,到这里,我们是从开始页循环到结束页。

作为一个程序员,而我们的程序之中会把结果输出到一个文件中。文件,资源呐,有资源的地方就有竞争,但是你看这个程序,并没有任何同步代码。而如果你运行了程序,会发现,文件中并不会出现把下一行后一半的文字输出到前一行的前一半文字之后这种类似的情况。为什么?啊,不得不又吹下linux了,在linux中,进程中写文件,操作系统会保证其原子性。也就是说,对于两个进程,你只管输出,不用担心其他的问题。而使用多进程的另一个好处就是,在你运行的这些进程之中,如果有一个进程挂了,并不会影响你另一个进程的执行。最终,你只不过是会少一些数据而已,不至于得到了错误的数据。

再回到上面一张图,我这里只用了两个进程,因为只有两个核,用三个进程必然至少有一个得不到执行。如果想使用更多的进程咋办?你只要调整下range里的步长参数,也就是最后一个参数,就可以完成进程的划分。当然,这个进程函数写的还不是那么的好,不过大体意思嘛是这个意思。

那么,按照下面这个步骤运行这个命令,如何证明我的程序是并发运行的呢?

在linux上,你只需要打开另外一个终端,输入top,你会看到这样的结果

第一行和最后一行,你会看到有两个python解释器在同时运行,有图有真相的证明了,程序确实是并行的在运行。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏张善友的专栏

从APM角度上看:NoSQL和关系数据库并无不同

Michael Kopp拥有十年以上C++、Java/JEE的架构及开发经验,现Compuware技术策略师,专攻大规模产品部署的架构和性能。 以下为译文: 传...

2338
来自专栏后端技术探索

纯干货--秒杀系统架构分析与实战

(1)查询商品;(2)创建订单;(3)扣减库存;(4)更新订单;(5)付款;(6)卖家发货

2784
来自专栏java工会

15个顶级Java多线程面试题及答案,快来看看吧

1585
来自专栏Android群英传

Android工程模块化平台的设计

694
来自专栏服务端技术杂谈

动手撸一个规则引擎

最开始听说过规则引擎可能是一个类似于OA的系统中,通过规则配置,让一个审批流程得到配置化和规则化。

1614
来自专栏在线教育技术团队专栏

对于服务端bug处理的一些建议

清楚bug所在业务的逻辑,了解正常的流程应该是什么,业务的入口在哪里,重现的步骤

1632
来自专栏顾宇的研习笔记

AWS 上的生产环境架构优化案例

在AWS 上的生产环境性能分析案例一文中,记录了我对客户应用生产环境的一次性能分析。接下来,我们要根据所发现的性能问题进行架构优化,以提升可用性和性能。同时,这...

1421
来自专栏owent

libatbus基本功能及单元测试终于写完啦

经过茫茫长时间的编写+过年在家无聊补充和修正单元测试,再加上这两天的整理,终于把以前的这个关于服务器通信中间件的基本功能和相应的单元测试完成啦。还是可以热烈庆祝...

922
来自专栏双十二技术哥

关于应用启动连续崩溃的解决思考

线上出现了大面积的崩溃或者各种不可用,那画面简直美的不敢想象。这也是任何商业项目做大之后都会花大力气在性能优化与高可用的原因,这个过程中也催生出了各种APM工具...

1184
来自专栏北京马哥教育

大型网站的灵魂——性能

Via: http://blog.jobbole.com/84433/ 前言 在前一篇随笔《大型网站系统架构的演化》中,介绍了大型网站的演化过程,期间穿插了一...

3256

扫码关注云+社区