自己动手做大数据系统(第2版)
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

3.3 抓取并解析HTML中的数据

3.3.1 使用Beautiful Soup提取网页内容

爬虫首先访问的是检索结果页面。接下来就要遍历每个页面。抓取单个新闻页面的代码定义在writePage方法中,代码片段如下:

第4、5行代码把爬虫“伪装”成浏览器去访问服务器。正常情况下通过PC端的浏览器、App或其他移动终端去访问Web服务器时,HTTP Request中都包裹着不同内容的请求头信息,服务器也可以凭此识别出该请求是通过何种浏览器发出的。而网络爬虫会直接通过一个Socket连接过来取数据(有一些“敏感”的服务器会拒绝这种方式)。第4行代码定义了一个浏览器描述,在第5行代码的requests.get()方法中附带着请求头信息去请求服务器。除了浏览器的类型之外,请求头信息还包括很多条目,读者可以参阅w3.org网站。不同的网站服务器所识别的请求头内容都不一样,大家只能通过代码手动测试。

第8、12行代码用Beautiful Soup的select()方法,按照CSS选择器去提取HTML页面中的新闻内容和发布时间。在图3-5的方框中,<div>标签中嵌套的<span></span>标签中的时间内容按照select("[class='article-sub'] > span")的语法规则进行提取。

图3-5 HTML源码中的<div>标签和类选择器名

提取后的内容是列表。这里取其第一个元素,得到的就是2018-03-06 13:44:27这段文本。

3.3.2 保存抓取内容

爬虫抓取后的内容可以写入数据库,也可以生成文本文件。在本项目中,爬虫所抓取的文章要导入Hive中。因此,以每条新闻为单位生成一个文本文件,并以新闻的ID作为文件名。参考代码如下:

第8行代码设定文本文件的输出路径和文件名。

第10~15行代码拼接文件内容。chr(1)是Python的字符转换函数,这里把ASCII码1转换为字符。该字符是不可见字符,也是Hive中表字段之间默认的分隔符。

输入命令python site2.py,运行爬虫代码。这时,会在/root/web_data/site2/目录下创建文件夹,并生成多个文本文件。

由于Hive处理多个小文件的效率很低,因此需要进行文件合并。这里,每个小文件里面只有一行数据,可以使用Python代码逐个读取每个文件,合并成一个多行的大文件。其具体代码定义在site2.py的mergeFile方法中,合并后的文件名为site2merge.dat。该文件的具体内容如图3-6所示,其中的黑块是Hive之间的默认列分隔符。

图3-6 文件合并后的内容示意图

文件中每列的内容包括站点标识、检索关键字、文章URL、发布时间、阅读数、文章标题和文章内容等。完整的Python代码和生成的文本文件可参考本书资源文件中的源码目录\ch3内容。

本书提供了两个模拟的文章站点。上面讲解的是如何抓取模拟站点2(site2)的文章。模拟站点1(site1)的抓取思路与此类似,读者可以查看本书资源文件中的相关代码。

3.3.3 不同爬虫模块所适用的场景

使用网络爬虫获取非结构化数据是大数据处理的第一步。在此,采用Python语言是首选。Python提供的网络爬虫模块较多,它们都有各自的特点和适用场景。

1)urllib模块和urllib2模块。在安装Python 2或Python 3时均自带这两个模块,无须单独安装。urllib2模块在Python 3中更名为urllib.request,使用该模块可以读取网页HTML代码或下载图片/视频等二进制文件。urllib2是urllib的增强版,但其并不是完全替代了urllib,二者经常搭配使用。

2)requests是需要单独安装的模块。其语法简单且功能强大,并可以模拟Cookie和Session登录。

3)Beautiful Soup是用来快速解析、提取HTML/XML节点内容的解析器。它像是一个工具包,要和urllib或requests配合使用。

4)Selenium是一款Web页面端的自动化测试工具。Selenium本来和爬虫没有直接关系,但由于其可以模拟触发JavaScript中的Ajax调用或模拟鼠标的移动或点击事件(而这些是爬虫无法实现的),因此可以和其他爬虫模块配合使用。

5)PlantomJS是一个跨平台的支持脚本运行的无请求头的浏览器。其一般是配合Selenium一起使用的。通过PlantomJS提供的代码可以模拟用户操作浏览器,为爬虫绕过服务器端的各种验证。需要注意的是,它在GitHub上的源码截至2018年3月已经不再更新。

6)Scrapy是一款开源的可伸缩的爬虫框架。相比于以上的几个爬虫组件,其更加结构化和更为高效。Scrapy集成了抓取→解析→落地3个环节,其不需要单独的解析器,并且以管道方式支持多种持久化方式,可以同时把抓取结果写入文件和写入数据库,也支持多线程抓取。本书第1版的第4章专门介绍了这个框架。