python 爬虫 入门 commit by commit -- commit5

"对于不重要的事情,就当没发生" -- by 我自己

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

这一个commit的代码,运行起来和上一个commit几乎没有什么不同,但是代码结构发生了比较大的改变。我的编程哲学之一就是不要过早的设计,至少不要在什么都没有的情况下就设计,因为很容易进入只讨论没啥进展的圈子之中。而我个人觉得,在你能糊出一个可以跑的程序之后,你觉得功能上也差不多就这样了,再开始就现有代码进行设计。不仅相当于检查了一遍试卷,而且还可以让你设计的至少更贴近于功能吧。我是一个TDD的绝对支持者,虽然在写这个的时候我没有TDD,无他,因为懒。但是如果给钱,我觉得支持TDD,因为人类对于错误的管理绝对是处于不超过2核的状态,发现不了错误是很正常的,在这个方面,靠程序比人靠谱。

重新设计或者重新构造一下代码第一步我觉得应该是看看代码中重复出现的代码,把这些提取成为函数,这是程序员的基本修养之一。我的几年经验告诉我,重复的代码不会对别人造成麻烦,只会给自己挖下很多坑。

而在这个代码中,重复的最多的就是构造BeautifulSoup类型的代码了。传入header,url,构造BeautifulSoup对象,虽然在后面寻找需要元素的部分略有不同,但是前面几乎没有任何差别,所以这就成为了第一个要变成一个函数的选取对象。另外一个一眼就能看穿的就是处理json字符串的部分了,在代码中,目前只有两个地方要处理json字符串,一个是获取价格,一个是获取好评率。虽然只有两个,但是俗话说有了2次就非常容易有n次,所以这就是我的第二个选择。于是我准备写两个函数GetBSObject和GetJson。函数本身很简单,就是把之前的代码放到一起了,但是提取成函数,你会发现有个很大的便利就是不用再写那么多遍的异常处理了。

前面我说过,异常在爬虫程序这种需要长时间而又要和情况很多的网络相结合的程序中特别的常见。说句站在程序员角度看起来是很吹牛逼的话,你的爬虫程序可能没有bug,但是一定会有异常情况。而如何处理这些异常我觉得挺哲学的,我能想到或者遇到的分这么几种情况。

  1. 不管,只是由catch块吞掉异常。
  2. 将异常输出到特定文件中,以后访问。
  3. 将异常抛出,在最外面的地方一并交给用户处理。

而我,作为一个觉得几粒老鼠屎坏不了一条河的水的支持者,加上人性本懒,果断而又坚决的采取第一种方法。在现代的网络环境中,长时间网络问题几乎不存在,几次没有采集到的数据,对海量数据影响有限。退一万步说,如果出现了长时间的网络异常,或者频繁的网络异常,那么输出到log中的海量数据也不会真的对改善程序有啥帮助。你最大可能会做的,是换个稳定的网络环境。而其余的程序本身逻辑导致的异常,大概率在爬虫程序中会导致数据明显不符合常理,一眼就能看出来。

虽然我嘴上这么说,但是在这两个函数中,一个我采取了输出错误信息到控制台的方法,一个我采用了pass,也就是忽略这个信息的方法。其实我的这个写的并不是很好,比如说在json那个函数中,我使用了finally,也就是无论在什么情况下,都要返回一个结果,哪怕是空字符串。而在后面正式处理的程序中,不得不又采用一个try catch而且貌似还在except中给出了一个疑似错误值的方法。原因是因为,我写到这里忘了考虑这个地方,但是commit已经commit进去了,所以,如果有兴趣的话,可以修改一下这里。

这个一个commit还有一个改动就是我把前几个commit中,在最后遍历字典信息然后输出改成了直接逐行输出,原因我在前面也提到过。对于我们这个程序,没有啥后续数据处理的,采用这种方式会更有交互感。如果你执行前面的程序,你会发现你要过很长时间才有输出,不仅让人怀疑自己的程序到底有没有出错,而且这种长时间没有任何交互的程序实在是不用户友好的典范。而采用简单的print,可以很方便的运用重定向,将输出输出到某个文件中。其实我觉得在没有数据库参与的情况下,这种情况就够用了。

这一个commit在代码上真的没啥可说的,我还是硬扯了那么多,这就是水平不够废话来凑。既然都凑了这么多废话,我想在最后再扯扯我对程序里异常处理的看法。异常是大部分语言中绕不开的话题,但是加入异常处理,至少在最直观上,你会发现代码变复杂了,可读性也差了。更不要说在运行时代码为了异常处理而膨胀的大小了。但是,又有很多人告诉你,在程序代码里不写异常处理貌似不是一个成熟程序员的做法。但是,垃圾的异常处理会吞掉程序的错误,很容易让程序在发生了问题之后根本不知道发生了什么。在C++里这种事情发生的简直就是用家常便饭来形容,所以go语言,没有异常,只有错误,我觉得逻辑上真的挺好。而我一般的做法是,如果这个程序是给别人使用的库,那么我会处理异常然后抛出,这样可以让第三方知道,我的库有问题了。而如果是本身的一个程序,我大多数情况下真的是在发生问题的时候让程序崩掉,毕竟,掩盖问题并不能解决问题,暴露问题才可以。

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

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

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏mukekeheart的iOS之旅

UML中几种类间关系:继承、实现、依赖、关联、聚合、组合的联系与区别

继承 指的是一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口)的功能,并可以增加它自己的新功能的能力,继承是类与类或者接口与接口之间 最常见的关系;...

26210
来自专栏撸码那些事

【封装那些事】不充分的封装

1232
来自专栏Python中文社区

用Python实现微信接口(三)

專 欄 ❈爱撒谎的男孩,Python中文社区专栏作者 博客:https://chenjiabing666.github.io ❈ 群消息 itchat 增加...

3108
来自专栏软件开发 -- 分享 互助 成长

虚拟存储管理

程序局部性原理:基于大量的程序运行特征的观察发现在一段时间内,一个程序的执行往往是呈现高度的局部性。 表现在以下两个方面: 时间局部性:若一条指令被执行,那么不...

2006
来自专栏DT乱“码”

java中接口的作用

很多JAVA初级程序员对于接口存在的意义很疑惑。不知道接口到底是有什么作用,为什么要定义接口。       好像定义接口是提前做了个多余的工作。下面我给大家总结...

22510
来自专栏take time, save time

python 爬虫 入门 commit by commit -- commit3

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

1382
来自专栏数据小魔方

R语言抓包实战——知乎live二级页面获取

之前曾经写过一篇关于知乎live课程信息爬取的短文,那个直接遍历的知乎live主页上展示的部分课程,仅仅是很小的一部分。 今日这一篇将是该小项目的升级版,直接对...

39010
来自专栏企鹅号快讯

Python循环控制之for

各位小伙伴们 大家周三愉快 今天我们要来共同探讨 另外一个在Python中 (严格的说实在所有语言中) 最重要的语句之一 For()循环控制语句 技术要点: f...

2086
来自专栏iOS122-移动混合开发研究院

实现iOS图片等资源文件的热更新化(零): 序

必要的序 以后在写系列文章,准备把基本的规划和动机等,单独作为一个小的序言部分给独立出来.序言部分,可以较为完整地交待系列文章的写作动机,所展示的编码技术可能的...

1968
来自专栏精讲JAVA

Gof设计模式之单例模式(一)

今天开始更新设计模式系列,题目中Gof指的是《Design Patterns: Elements of Reusable Object-Orie...

2175

扫码关注云+社区

领取腾讯云代金券