第 5 章 网络数据获取 随着互联网的快速发展,有效提取并利用海量网络数据很大程度上决定了 解决问题的效率和质量。传统的通用搜索引擎作为辅助程序员检索信息的工 具,无法针对特定的目标和需求进行索引,也无法满足有效数据获取和信息发 现的高质量需求。面对结构越来越复杂,信息含量越来越密集的网络数据,为 了按照特定需求定向抓取并分析网页资源,实现更高效的指定信息获取、发现 和利用,网络爬虫应运而生。 ..5.1 网络爬虫简介 1.网络爬虫的定义 5.1 网络爬虫(WebSpider)又称网络机器人、网络蜘蛛,是一种根据既定规则, 自动提取网页信息的程序或者脚本。传统爬虫以一个或若干初始网页的统一 资源定位符(UniformResourceLocation,URL)为起点,下载每一个URL指定 的网页,分析并获取页面内容,并不断从当前页面抽取新的URL放入队列,记 录每一个已经爬取过的页面,直到URL队列为空或满足设定的停止条件为止。 网络爬虫的目的在于将互联网上的目标网页数据下载到本地,保存在数据库中 或本地数据文件中,以便进行本地数据文件操作和后续的数据分析。网络爬虫 技术的兴起源于海量网络数据的可用性,使用爬虫技术能够较为容易地获取网 络数据,通过数据分析得出有价值的结论。 5.2 网络爬虫的类型 1. 按照系统结构和实现技术,网络爬虫大致分为四种类型:通用网络爬虫 (GeneralPurposeWebCrawler)、聚焦网络爬虫(FocusedWebCrawler)、增量 式网络爬虫(IncrementalWebCrawler)以及深层网络爬虫(DepWeb Crawler)。实际应用中的网络爬虫系统通常是几种爬虫技术相结合实现的。 1.通用网络爬虫 通用网络爬虫又称全网爬虫,爬行对象从一些种子URL扩充到整个Web 第5章网络数据获取161(万维网), 主要为门户站点搜索引擎和大型Web服务提供商采集数据。这类网络爬虫 的爬行范围和数量巨大,对爬行速度和存储空间要求较高,而对爬行页面的顺序要求 相对较低,通常采用并行工作方式应对大量待刷新的页面,适合为搜索引擎获取广泛 的主题。 通用网络爬虫大致由页面爬行模块、页面分析模块、链接过滤模块、页面数据库、 URL 队列和初始URL 集合等几部分构成。为了提高工作效率,通用网络爬虫可以采用 深度优先和广度优先等爬行策略。采用深度优先爬行策略的爬虫按照深度由低到高的顺 序,依次访问下一级网页链接,直到不能再深入为止。爬虫在完成一个爬行分支后返回上 一个链接节点进一步搜索其他链接。当所有链接遍历完毕,爬行任务结束。这种爬行策 略比较适合垂直搜索或站内搜索,但爬行页面内容层次较深的站点时会造成资源的巨大 浪费。采用广度优先爬行策略的爬虫按照网页内容目录层次深浅来爬行页面,优先爬取 目录层次较浅的页面。当同一层次的页面爬行完毕,再深入下一层次继续爬取。这种爬 行策略能够有效控制页面的爬取深度,避免在遇到一个无穷深层分支时无法结束爬行的 问题。该策略无须存储大量的中间节点,不足之处是需要较长时间才能爬行到目录层次 较深的页面。 2.聚焦网络爬虫 聚焦网络爬虫又称主题网络爬虫,它会选择性地爬取与预定主题相关的页面。与通 用网络爬虫相比,聚焦网络爬虫只需爬取与主题相关的页面,极大地节省了硬件和网络资 源,保存页面数量少且更新快,可以更好地满足特定人群对特定领域信息的爬取需求。 页面内容和链接重要性不同导致链接的访问顺序也不一样,因此聚焦爬虫的爬行策 略分为以下四种。 基于内容评价的爬行策略将文本相似度计算方法引入网络爬虫中。该策略以用户输 入的查询词为主题,将包含查询词的页面视为主题相关页面,其局限性在于无法评价页面 与主题相关度的高低,可以尝试利用空间向量模型计算页面与主题的相关度。 页面链接指示了页面之间的相互关系,基于链接结构的搜索策略利用这些结构特征 评价页面和链接的重要性,以此决定搜索顺序。其中,PageRank算法是这类搜索策略的 代表,具体做法是每次选择PageRank值较大的页面链接进行访问。 基于增强学习的爬行策略将增强学习引入聚焦爬虫,利用贝叶斯分类器,根据网页文 本和链接文本对超链接分类,为每个链接计算重要性,从而决定链接的访问顺序。 基于语境图的爬行策略通过语境图学习网页之间的相关度。该策略训练一个机器学 习系统,计算当前页面到相关Web页面的距离,优先访问距离近的页面链接。 3. 增量式网络爬虫 增量式网络爬虫对已下载的网页采取增量式更新策略,只爬行新产生或已经发生变 化的网页,在一定程度上保证爬行尽可能新的页面。与周期性爬行和刷新页面的爬虫相 比,增量式爬虫按需爬取新产生或发生更新的页面内容,有效减少了数据下载量并及 时更新爬行过的网页,减少时间和空间上的耗费,但是增加了爬行算法的复杂度和实 162Python数据分析案例教程(微课版) 现难度。 为了保持本地存储的页面为最新页面,增量式爬虫通过监测网页数据的更新情况,持 续更新本地的页面内容。采用统一更新法的爬虫以相同的频率访问所有网页,不考虑网 页的改变频率。采用个体更新法的爬虫根据个体网页的改变频率重新访问各页面。采用 基于分类的更新法的爬虫根据网页改变频率分为更新较快网页子集和更新较慢网页子集 两类,然后以不同的频率访问这两类网页。 为了保证爬取的页面质量,增量式爬虫需要对网页的重要性进行排序,常用广度优先 策略和PageRank优先策略;也可以采用自适应方法,根据历史爬取结果和网页实际变化 速度对页面更新频率进行调整;或者将网页分为变化网页和新网页两类,分别采用不同的 爬行策略。 4.深层网页爬虫 Web页面按照存在方式可以分为表层网页和深层网页两类。表层网页是指传统搜 索引擎可以索引到的页面,以超链接可以到达的静态网页为主。深层网页是指隐藏在搜 索表单后,大部分内容不能通过静态链接获取,只有用户提交关键词才能获得的Web页 面。深层网页是目前互联网上最大、发展最快的新型信息资源。 深层网页爬行过程中最重要的部分就是表单填写,表单填写方法可以分为两类。 基于领域知识的表单填写:此方法一般会维持一个本体库,通过语义分析来选取合 适的关键词填写表单。一种方法是将数据表单按照语义分配到各个组中,每组从多方面 注解,结合各种注解结果预测最终的注解标签;也可以利用一个预定义的领域本体知识库 识别深层网页内容,同时利用Web站点导航模式自动识别填写表单时所需的路径 导航。 基于网页结构分析的表单填写:此方法一般无须领域知识或仅利用有限领域知识, 将网页表单表示为文档对象模型(DocumentObjectModel,DOM), 从中提取表单字段 值。一种方法是将HTML(HyperTextMarkuplanguage,超文本标记语言)网页表示为 DOM 树形式,对单属性表单和多属性表单分别处理;也可以将Web文档构造成DOM 树,将文字属性映射到表单字段。 5.3 网络爬虫基本架构 1. 网络爬虫主要完成两个任务,即下载目标网页和从目标网页中解析信息。一个简单 网络爬虫的基本架构如图5-1所示。 图5- 1 网络爬虫基本架构 第5章网络数据获取163 1.URL 管理模块 URL 管理模块负责管理URL 链接,维护已经爬行的URL 集合和计划爬行的URL 集合,防止重复爬取或循环爬取。其主要功能包括:添加新的URL 链接、管理已爬行的 URL 和未爬行的URL 以及获取待爬行的URL 。 URL 管理模块的实现方式有两种:一种是利用Python集合数据类型不包含重复元 素的特点达到去重效果,防止重复爬取或循环爬取;另一种实现方式是在数据库表的记录 中增加一个URL 标志字段,例如,已爬行的网页链接标记为“1”,未爬行的网页链接标记 为“0”。当有新链接产生时,先在已爬行的链接集中查询,如果发现该链接已被标记为“1,(”) 那么不再爬行该URL 的链接页面。 2. 网页下载模块 这是网络爬虫的核心组件之一,用于从URL 管理模块获取待爬行的URL,并将对 应的页面内容下载到本地,或者以字符串形式读入内存,方便后续使用字符串相关操 作解析网页内容。 Python第三方库requests是一个处理HTTP(HyperTextTransferProtocol,超文 本传输协议)请求的模块,其最大优点是程序编写过程更接近正常的URL 访问过程。 3. 网页解析模块 网页解析模块是网络爬虫的另一个核心组件,用于从网页下载模块获取已下载的网 页,并解析出有效数据交给数据存储器。网页解析的实现方式多种多样。由于下载到本 地的网页内容以字符串形式保存,可以使用字符串相关操作从中解析出有价值的结构化 数据,例如,可以使用正则表达式指定规则,然后根据规则找出感兴趣的字符串;也可以使 用Python自带的HTML 解析工具html.arser从网页内容的字符串中解析出相关信 p 息;还可以使用Python第三方库beautifulsoup4实现网页解析。作为一种功能强大的结 构化网页解析工具,beautifulsoup4模块能够根据HTML 和XML(ExtensibleMarkupLanguage,可扩展标记语言)语法建立解析树,进而高效解析和处理页面内容。 4. 数据存储器 数据存储器负责将网页解析模块解析出的数据存储起来,用于后续的数据分析和 信 息利用 。 ..5.2 网页下载模块 网页下载模块将URL 对应的网页下载到本地或读入内存。Python提供了第三方库 requests访问一个指定的URL,返回有用的数据。 1 64 Python数据分析案例教程(微课版) 5.2.1 requests库简介 requests是一个处理HTTP请求的Python第三方库,需要预先安装。requests模 块在Python内置模块的基础上进行了高度封装,使得进行网络请求时更加简洁和人 性化。 requests库支持丰富的链接访问功能,包括HTTP长链接和链接缓存、国际域名和 URL获取、HTTP会话和Cookie保持、浏览器使用风格的SSL验证、自动内容解码、基 本摘要身份验证、有效键值对的Cookie记录、自动解压缩、Unicode响应主体、HTTP(S) 代理支持、文件分块上传、流式下载、连接超时和分块请求等。 5.2.2 requests库的使用 1.requests库的网页请求方法 通过URL访问网络链接并返回网页内容是requests模块的基本功能,其中与网页 请求相关的函数有6个,具体使用方法如表5-1所示。 表5-1 requests模块的网页请求函数 函 数说 明 get(url[,timeout=n]) 对应HTTP 的GET 方式,获取网页最常用的方式,可选参数 timeout设定每次请求超时时间,单位为秒 post(url,data={'key':'value'}) 对应HTTP的POST方式,其中字典用于传递客户数据 delete(url) 对应HTTP的DELETE方式 head(url) 对应HTTP的HEAD方式 options(url) 对应HTTP的OPTIONS方式 put(url,data={'key':'value'}) 对应HTTP的PUT方式,其中字典用于传递客户数据 requests.get()函数向目标网址发送请求,接收响应,返回一个response对象。这里 的参数url必须采用HTTP或HTTPS方式访问。 In [1]: import requests url ='https: //www.baidu.com/' r_obj =requests.get(url) type(r_obj) Out[1]: requests.models.Response 2.response对象 调用requests.get()函数后,返回的网页内容保存为一个response对象。response对 象的常用属性如表5-2所示。 第5章 网络数据获取1 65 表5-2 response对象的常用属性 属 性说 明 status_code HTTP请求返回的状态码,为整数,200表示连接成功,404表示连接失败,500表示内 部服务器错误等 headers HTTP响应内容的网页header信息 encoding HTTP响应内容的编码形式 text HTTP响应内容的字符串形式,即url对应的页面内容 content HTTP响应内容的二进制形式 调用requests.get()函数后,可以使用response.status_code属性返回HTTP请求之 后的状态,如果请求未被响应,需要中止内容处理;否则系统返回一个response对象,其 中存储了服务器的响应内容。大多数情况下,requests用户可以使用response.text获取 文本形式的响应内容,requests自动解析服务器内容;也可以使用response.encoding属性 返回页面内容的编码方式,可以为encoding属性赋值更改编码方式,便于处理中文字符。 实际上,requests也可以基于HTTP头部信息对相应编码做出有根据的推测,使用正确的编 码方式访问response.content,以字节形式直接保存返回的二进制数据。 In [2]: r_obj.status_code #状态码 Out[2]: 200 In [3]: r_obj.headers #网页header 信息 Out[3]: {'Cache-Control': 'private, no-cache, no-store, proxy-revalidate, no -transform ', ' Connection ': ' keep - alive ', ' Content - Encoding ': ' gzip ', ' Content- Type': 'text/html', 'Date': 'Fri, 05 Feb 2021 01: 52: 06 GMT', 'Last- Modified': 'Mon, 23 Jan 2017 13: 23: 55 GMT', 'Pragma': 'no- cache', 'Server': ' bfe/1.0.8.18', 'Set- Cookie': 'BDORZ= 27315; max- age= 86400; domain=.baidu. com; path=/', 'Transfer-Encoding': 'chunked'} In [4]: r_obj.encoding #网页编码 Out[4]: 'ISO-8859-1' In [5]: r_obj.text #请求返回的文本信息, 出现乱码 Out[5]: ' \r\n < html> < head> < meta http - equiv= content-type content=text/html;charset=utf-8>
内容 strings HTML页面所有呈现在Web上的字符串,即标签的内容 stripped_strings HTML页面所有呈现在Web上的非空格字符串 In [2]: bs.head Out[2]:
< meta content="text/html;charset= utf- 8" http- equiv="content -type"/> < meta content =" IE = Edge" http - equiv =" X - UA - Compatible"/> < meta content="always" name ="referrer"/> < link href =" http://s1. bdstatic. com/r/ www/cache/bdorz/baidu.min.css" rel="stylesheet" type="text/css"/> < title> 百 度一下,你就知道 第5章 网络数据获取1 69 In [3]: bs.title #每一个对应HTML Tag 的属性是一个Tag 类型 Out[3]: