谭升
非主流人工智能科学家 我和外面那些妖艳的货不一样

【爬虫】3.3 数据抓取

还是原来那句:我不是爬虫专家或者前端后台专家,我的努力方向也不是这个方向,我只是想要运用这套技术,但是我又希望对整个过程有一个比较详细的了解,所以我在本系列只是简单介绍,有些东西可能含糊不清,需要详细学习的同学可以去查询相关资料

分析网页

前面讲的三只虫已经讲解了如何把静态的网页下载回本地,前两篇HTTP讲了下背后的理论基础,就是向服务器发送请求,得到相应的过程,按照Introduction中介绍的处理过程

我们在得到内容后就要进行分析内容了,也就是抓取感兴趣的信息,可以是数据,比如文章,图片,也可以是链接,那么就是下一步要访问的页面了。
分析网页的方法是使用浏览器自带的工具,比如Safari和Chrome的右键都能显示源代码(检查元素)之类的功能

这个源代码(html)就是我们上面用虫子下载到的,而接下来,就是要提取里面的信息了,想要啥,就拿啥。

抓取方法

正则表达式

正则表达式,是比较好使用,但是通用性不强的一种方法,其实也不是很好用,因为你要首先掌握正则表达式的语法,而掌握了正则表达式的语法以后,你会发现,处理字符串类的文件会变得极其简单,高效,但是正则表达式本身就是个难点,会正则表达式的人也不是那么特别的多,比如我们看下面这个例子,还是上文我们讲的最后一只虫子:

在函数get_link里面

html是服务器返回的响应,这里的类型就是字符串:

然后我们在这个字符串里找出所有满足

的模式,于是我们就得到了

对比原始HTML确实提取到了所有的url但是并不是很干净所以代码中进一步筛选根据的特性就是网站的所有连接里都有’view’ 这个关键字

上面使用的是三只虫里面的代码,其中这两部用到了正则表达式,一个用于提取,一个用于确定,可以看出,正则表达式其实不是很通用,每个网站甚至每个网页都要对应自己的表达式,所以这个基本算是半自动模式,过段时间如果网页代码发生改变,那么正则表达式可能会失效。

Beautiful Soup

上面的正则表达式是半自动武器,那么Beautiful Soup就是AK47,自动化,强壮,而且好用不贵。
安装方法就是

与正则表达式不同的是,Beautifulsoup并不是把响应当成字符串处理,而是将html字符串解析成soup文档,相当于构建成了自己的数据结构,然后在使用自己的方法解析,查找,完成一些任务。
但是html有些常见的问题,比如有些语法的缺失:

其中Area和Population都缺失后边的’/li’,那么这种情况可以有两种解释,Population是Area的子元素,另一种他们两个是并列的。Beautifulsoup可以给出以下处理:

得到的输出是:

明显已经被修复了,层次已经明确了,就是并列关系。
bs中find命令和find_all能够找出第一个或者所有的你关心的标签

而且找到结果还是bs类的,可以继续使用find和find_all在结果中搜索。
代码过程复杂在构建bs数据结构那步,需要显示的初始化,其他部分就相对正则表达式简单多了。

Lxml

xml解析库的python封装版本,解析速度比Beautiful Soup快很多,但是安装有点复杂。
其用法与BeautifulSoup类似。具体可以参考手册,而且其可以利用CSS选择器完成一些高难度的任务

性能

以上三种方法性能是有差距的,很明显lxml使用c语言的封装的,应该跑的最快,而Beautiful Soup应该是最慢的,因为有重建过程。而正则表达式也应该是比较快的(也是C语言封装出来的工具箱)
经过测试,有一下的结论可供参考(来自“用python写网络爬虫”)

抓取方法 性能 使用难度 安装难度
正则表达式 困难 简单(内置模块)
Beautiful Soup 简单 简单(纯python 模块)
Lxml 简单 相对困难

添加抓取回调

之前我们讲到的三只虫,只讲到如何访问网站所有的网页,这相当于我们转悠了一圈啥也没干,如果要处理点什么问题,比如下载个图片什么的,就要加入响应的功能,为了写一个通用的遍历网站的爬虫,处理问题部分用一个单独的函数,而这个函数作为参数传给遍历网站的模块,这种方法在C++中叫函数指针,这里我们可以称之为回调函数。
再次说明下,我们有一个框架,这个框架可以访问网站中的所有网页,但是框架为了通用性,没有设置每一页具体完成什么动作,而这个动作留作接口供大家发挥,这个接口就是回调函数(C++叫函数指针)

下面我们改造下三只虫中的代码,加入回调函数:

与原始函数不同的是,我们在这里没有使用固定的获取url的函数get_url(),而是把其作为参数传递进来,这样函数将会更加通用,提示一下,这里面关于最大深度的设定没有实现,如果想使用这段代码,请大家自己添加。
get_url也可以实现任何我们想要的功能,这里就不再赘述了,比如将数据写入文件什么的。

总结

本文我们介绍了三种抓取数据的方法,当然是我们关心的数据,同时也通过回调函数的实现,使得框架更为通用。我们下一篇该讲如何高速下载了。
待续。。

Share

You may also like...

说点什么

avatar
  Subscribe  
提醒

由于博客移至wordpress,部分公式和代码显示不正常,博主正在努力修改,如发现公式显示错误,请及时在文章下留言,感谢您的帮助,尽请原谅!