基于R语言的自动数据收集:网络抓取和文本挖掘实用指南【1.5】

张开发
2026/5/6 0:19:08 15 分钟阅读
基于R语言的自动数据收集:网络抓取和文本挖掘实用指南【1.5】
第3章 XML和JSONXMLeXtensible Markup Language可扩展标记语言是在网络上交换数据最流行的格式之一。不仅如此它在我们的日常生活中也是无所不在的。正如Harold和Means2004xiii提到的对于横跨几乎所有计算机应用的全新设计的文档格式XML已经成为其语法的首选。它用在Linux、Windows、Macintosh和很多其他的计算机平台上。华尔街的主机通过交换XML文档来进行股票的交易。在自己家里的PC上玩游戏的孩子用XML保存他们的文档。体育迷以XML格式在他们的手机上接收实时比分。XML是迄今为止所发明的最稳定、最可靠和最灵活的文档语法。对于某些具备了HTML基本知识的同学来说XML看起来会很眼熟因为它有和其他标记语言相同的特性。不过HTML和XML有它们各自的用处。HTML用于构成信息的展示而XML的主要用途是保存数据。因此XML文档的内容在浏览器中打开时并不会变得多好看——XML只是包裹在用户自定义标签里的数据而已。用户自定义标签使XML对于保存数据比HTML灵活得多。本章的主要目的不是让你变成XML编程专家而是让你熟悉XML文档的关键部件。我们一开始会看到一个实际的XML例子3.1节接着是XML语法的介绍3.2节。有很多种方法可以用于限制XML标记里的无限灵活性。本书3.3节和3.4节会介绍一些扩展XML的技术以及定义新标准的技术通过它们可以简化在网络上高效率地交换特定数据的工作。3.5节介绍如何在R里处理XML数据。如果你的网络抓取任务并非特定针对XML数据那你只需要大概浏览一下本章的这部分内容就可以了因为你从第2章已经熟悉了XML最重要的一些概念。另一个常用的网络数据存放和交换的标准是JavaScript对象标记JSON。JSON在数据交换用途方面是XML越来越流行的替代品它具备一些更好的特性。因此本章的第二部分会转向JSON。我们会用一个小例子介绍这种格式3.6节讨论它的语法3.7节并学习如何把JSON内容导入R并处理其中的信息3.8节。3.1 XML文档示例让我们从一个XML文件的简短例子开始。图3-1中的XML代码提供了有关三个James Bond007系列电影的样本还有一些基本信息。也许XML代码最有特色的地方就是人类阅读者可以毫无困难地解析其中的数据。XML里的值和名字都被包裹在有含义的标签里。这三部电影中的每一个都带有名字、年份、两位主演、预算和票房收入。缩进的层次对于阅读也提供了很多的辅助但并不是XML所必需的部件。它的作用只是突出文档的层次结构。这个文档以根元素bond_movies开始也以它结束。对于每个电影记录其中的元素是重复的而内容则各不相同。某些元素是特殊的。第一行的元素xmlhttp://www.hzcourse.com/resource/readBook? path/openresources/teach_ebook/uncompressed/15597/OEBPS/Text/...没有重复出现它和actors都在http://www.hzcourse.com/resource/readBook?path/openresources/teach_ebook/uncompressed/15597/OEBPS/Text/...符号内部包含了一些额外的信息。XML语言的工作方式非常直观。即使你还没有掌握语法的所有规则扩展及改善这个数据集对你来说应该也不成问题。实际上为什么不试试呢复制文件打开维基百科查找电影的其他细节信息然后把找到的信息加入文件中然后你可以检查一下你的XML代码写得是否正确。这是因为信息是作为纯文本存放的标签则完全是用户自定义且容易理解的这样可以把数据整理成含义明确的方式。其实标签对于解析数据也不一定是必需的但它们让XML成为了一种计算机语言从而能为计算机的通信发挥作用。XML是纯文本格式这一事实使它具备终极兼容能力。这意味着不管我们使用的是什么浏览器什么操作系统还是哪个PC硬件平台我们都能处理它。要解析其中的数据和结构亦无须更多的信息或解码器。标签和数据一起传输就完整地描述了文档这通常称为自描述。此外因为标签是互相嵌套的所以XML文档可以用于表示复杂的数据结构Murrell 2009p.116。我们会在后续章节讨论这些结构。需要指出的是虽然XML如此灵活但它也具备一套清晰的规则用于定义文档的基本布局。我们可以使用简单的工具来检查在XML文档中是否遵守了这些规则。[1]另外还有一些工具用来进一步限制XML文档的结构和内容。很多开发者使用XML的语法来创建新的基于XML的语言这些语言基本上会限定XML使用一组固定的元素、结构和内容在3.4.3节和3.4.4节会深入探讨这些内容。这些衍生语言仍然是合法的XML。XML通过这些扩展应用获得了相当大的流行度。在XML文件中存放信息的不足之处是效率不高。纯文本XML文档往往包含了很多冗余信息。注意在标准XML里每个数据项的起始和闭合标签都是重复的。这样文档就消耗了比真实数据更多的存储空间。特别是当我们处理大数据集或具备高度层级化结构的数据时尝试导入和操作这些数据都会消耗很多内存。对于打开XML文件的操作比较好用的是那些能突出文档语法并根据元素在层级结构中的层次产生自动缩进的程序。所有主流浏览器的当前版本都具备充分的XML文件解析能力你常用的代码编辑器很可能也具备XML标识功能。不过请注意有的XML文件可能会非常大包含上百万行数据所以打开它们会需要不少时间。在下面的章节我们会继续讨论XML的语法。我们会学习如何把XML数据导入R里以及如何将其转化为其他更便于分析的数据格式。我们还会介绍其他用于存放多种类型的数据的XML衍生结构。你也许会对依赖于XML的大量应用程序以及如何利用这些知识进行数据抓取感到惊讶。[1] 不过作为只是被动读取文档的XML用户我们很少对这类语法检查工具感兴趣。3.2 XML语法规则和其他任何计算机语言一样XML也有一套语法规则和关键元素要看懂XML文档就必须了解这些内容。不过别害怕XML规则是非常简单的。3.2.1 元素和属性再看一眼图3-1。它解释了我们需要了解的XML知识的很大一部分。一个XML文档永远以声明XML文档的一行代码开头version1.0声明了所用的XML版本号。目前有两个版本XML 1.0和XML 1.1。[1]此外虽然并非必要但这个声明中可以包含文档的字符编码格式在本例中是encoding“ISO-8859-1”。[2]声明中可以包含的另一个属性但是我们的例子中没有是standalone它的取值是yes或no用于指示是否有外部标记声明会影响文档的内容。[3]XML文件必须有且仅有一个根元素它包裹了整个文档。在我们的例子里根元素是信息通常是存放在元素中的。一个XML元素由它的起始标签和内容定义。一个元素常常有一个闭合标签但也可以在起始标签里用一个斜杠/闭合。它里面可以包含·其他元素。·属性是从更多细节来描述元素的信息。属性和元素一样是存放信息的位置但它们的内部不能再包含更多的元素或属性了。·数据任何形式和长度的如文本、数字或符号。·所有合法内容的混合体听起来挺复杂的但一个元素包含其他带有数据的元素其实是一种很常见的情况。例如图3-1里的元素都包含了一个属性、其他元素以及子元素里的数据。·空白完全的空白——没有数据没有其他元素连个空格都没有。我们来看一下上述XML文档中的第一个title元素它的组成部分有元素标题 title起始标签 title终止标签 /title数据值 Dr.No我们已经从HTML里熟悉了起始标签——终止标签的逻辑关系。这种语法的优点是我们很容易就能在文档中定位某个特定元素的数据不管它在第几行或第几层。在上述例子中title出现了三次。通过创建一个类似于“把所有名字是title的元素的内容给我”的查询我们可以获取所有这三个元素。这就是在第4章会介绍的内容即如何使用查询语言XPath。更紧凑的组织元素的方式如下这个元素包含了元素名 actors起始标签 actorshttp://www.hzcourse.com/resource/readBook? path/openresources/teach_ebook/uncompressed/15597/OEBPS/Text/.../第一个属性名 bond第一个属性值 Sean Connery第二个属性名 villain第二个属性值 Joseph Wiseman在这个例子中没有终止标签只有一个起始标签。这就是所谓的空元素因为元素中不包含数据。空元素都是以一个斜杠/闭合的。当然如果要咬文嚼字例子中的元素其实并不是空白的。正如在HTML里一样XML元素也能包含提供更多信息的属性。一个元素可以包含的属性是无限的。上例中的元素有两个属性。它们用一个空格分开。属性永远是起始标签的一部分它们的取值放在引号里前面是一个等号。存放在属性里的信息称为属性值。属性值必须放在引号里可以用单引号如bondSean Connery或双引号如bondDaniel Craig。不过如果属性值本身带有一种引号你就必须用另一种引号在里面放属性值了由于XML文档的结构具有先天的灵活性存放同样的内容会有很多不同的方式。注意在图3-1的实例中演员信息的存放方式。另一种存放方式也可以是这样的所有的信息都保留了不过演员的名字出现在存放在元素而不是属性里。这两种方式都是合法的。属性的问题是不能继续分支因为属性不能扩展而且只能包含一个值。另外我们发现和元素相比属性更难读取提取数据也更为不便。不过它们也并非一无是处。看一眼图3-1中的代码。名为id的属性值可以用来使同名的元素具备唯一的识别号。在我们需要操作XML树中某个特定元素的信息时这种特性就用得上了。3.2.2 XML结构每个XML文档都可以表示为一个层级树。这种数据以层级形式存放的情况非常适合我们面临的多种数据结构调查对象按国家进行嵌套。调查对象的反馈意见按调查对象进行嵌套。选票按投票站进行嵌套投票站又按选区进行嵌套选区又按国家进行嵌套以此类推。图3-2给出了图3-1中XML代码的图形化表示。最顶部的是根元素bond_movies。所有其他元素有且只有一个父节点。实际上我们可以用一个家族树来对整个文档进行类比把每个元素描述为一个节点·movie节点是根节点bond_movies的孩子·movie节点互为兄弟·bond_movies节点是movie节点的父亲而movie节点是title…boxoffice等节点的父亲·title…boxoffice等节点是bond_movies节点的孙子。注意在图3-2中属性及其取值是在元素值的方框里表示的尽管它们也可以看作XML树中的下一级叶子节点。不过因为属性不能是其他元素或属性的父节点所以它们其实只是描述元素的内容而不是独立节点。元素之间必须严格嵌套这意味着不允许交叉嵌套。非法文档结构的一个例子如下所示从理论上说取值为Jonathan的child元素可以成立一个新的family分支里面包含了Jonathan的妻子Julia和他们的孩子Jeff这样也是说得通的。问题在于Jonathan所在的child元素必须在整个家庭的family元素之内闭合。3.2.3 命名及特殊字符XML的长处之一是我们基本上可以任意选择元素的名字。不过也有一些命名规则·元素名字可以是字母、数字和其他字符的组合如name1…/name1。类似 、 、ü、é、è或à的特殊字符也是可以用的但是最好不要用它们会限制XML文件的跨系统兼容性。·名字不能以数字开头如123namehttp://www.hzcourse.com/resource/readBook? path/openresources/teach_ebook/uncompressed/15597/OEBPS/Text/.../123name。·名字不能以英文句号开头如.namehttp://www.hzcourse.com/resource/readBook? path/openresources/teach_ebook/uncompressed/15597/OEBPS/Text/.../.name。·名字不能以xml或者XML、Xml等大小写变体的字母组合开头如xml.rootnamehttp://www.hzcourse.com/resource/readBook? path/openresources/teach_ebook/uncompressed/15597/OEBPS/Text/.../xml.rootname。·元素和属性的名字是区分大小写的。movie、MOVIE或Movie都不一样。·名字不能包含空格如my familyhttp://www.hzcourse.com/resource/readBook? path/openresources/teach_ebook/uncompressed/15597/OEBPS/Text/.../my family。和HTML的情况类似有一些字符因为在标记中有特殊用途所以不能直接原样地用在内容中。要在内容里表示这些字符就必须用转义字符串来代表它们。这些实体在表3-1里列出用法如下所示特殊字符也不一定每次都需要转义。例如有时候引号就不用上例中的RichardJawsKiel引号的含义是明确的因为属性值已经被双引号括起来了。在XML元素值中使用引号通常也没有太大问题因为它们在元素值里没有什么特殊含义仅仅是在标签内部作为属性值的限定符而已。

更多文章