数据与智能 本公众号关注大数据与人工智能技术。由一批具备多年实战经验的技术极客参与运营管理,持续输出大数据、数据分析、推荐系统、机器学习、人工智能等方向的原创文章,每周至少输出7篇精品原创。同时,我们会关注和分享大数据与人工智能行业动态。欢迎关注。
来源 | Data Science from Scratch, Second Edition
作者 | Joel Grus
译者 | cloverErna
校对 | gongyouliu
编辑 | auroral-L
全文共6018字,预计阅读时间40分钟。
第九章 获取数据
9.1 stdin 和 stdout
9.2 读取文件
9.2.1 文本文件基础
9.2.2 分割的(delimited)文件
9.3 网络抓取
9.3.1 HTML和解析方法
9.3.2 例:密切关注国会
9.4 使用API
9.4.1 JSON(和XML)
9.4.2 使用无验证的API
9.4.3 寻找API
9.5 案例:使用 Twitter API
9.6 延伸学习
写作本书我用了三个月的时间;构思只用了三分钟;而收集书中的数据,则用了我的一生。
——F. 斯科特 · 菲兹杰拉德
为了成为一名数据科学家,你需要数据。事实上,作为数据科学家,你会花很大一部分时间来获取、清理和转换数据。必要时,你总可以自己输入数据(或者可以让你的助手来做),但通常这样做比较浪费时间。本章我们来看看利用 Python 获取数据并得到正确格式的不同方法。
9.1 stdin和stdout
如果在命令行运行 Python 脚本,你可以用 sys.stdin 和 sys.stdout 以管道(pipe)方式传递数据。例如,以下脚本按行读入文本,然后输出与一个正则表达式匹配的行:
然后对收到的行计数并输出计数结果:
你可以用这种方法来计数文件中有多少行包含数字。在 Windows 中,你可以用:
而在 Unix 系统中,你可以用:
“|”运算符是个管道字符,它的意思是“使用左边命令的输出作为右边命令的输入”。可以使用这种方法精心设计数据处理的管道。
注意
如果你使用的是 Windows,你可以在这行命令中去掉所包含的 python 部分:
如果你在Unix系统上,那么这样做需要更多的步骤。首先添加一个“Shebang”作为脚本#!/usr/bin/env python的第一行。然后,在命令行中,使用chmod x egrep.py使文件可执行。
类似地,下面的这个脚本计算了单词的数量并给出了最常用的单词:
之后你可以做这样的事情:
(如果你正在使用Windows,那么使用type而不是cat。)
注意
如果你是个 Unix 编程老手,你可能会很熟悉系统里许多内置的命令行工具 (比如 egrep),但你自己从零开始创建这些工具或许更好一些。毕竟,用到的时候刚好知道,总是好的。
9.2 读取文件
可以显式地用代码来读写文件。用 Python 处理文件非常简便。
9.2.1 文本文件基础
处理文本文件的第一步是通过 open 命令来获取一个文件对象:
因为非常容易忘记关闭文件,所以你应该在 with 程序块里操作文件,这样在结尾处文件会被自动关闭:
如果需要读取一个完整的文本文件,可以使用 for 语句对文件的行进行迭代:
按这种方法得到的每一行会用换行符来结尾,所以在对读入的行操作之前会经常需要用strip() 来进行处理。
例如,假设你有一个写满电子邮件地址的文件,每个地址一行,你想利用这个文件生成域名的直方图。正确地提取域名的规则有些微妙--如公共后缀列表,但一个好的近似方案是只取出电子邮件地址中 @ 后面的部分。(对于像 joel@mail.
datasciencester.com 这样的邮件地址,会给出错误的答案,但为了本例,我们愿意接受):
9.2.2 分割的(delimited)文件
我们刚刚处理的假想电子邮件地址文件每行只有一个地址。更常见的情况是你会处理每一行包含许多数据的文件。这种文件通常是用逗号分割或tab分割的:每一行有许多字段,用逗号或tab来表示一个字段的结束和另一个字段的开始。
这开始变得复杂了,各字段中带有逗号、tab 和换行符(这是你不可避免地要处理的)。因为这个原因,几乎总是会犯的一个错误是你自己尝试去解析它们。相反,你应该使用Python的csv模块(或者pandas库,或其他一些设计用来读取逗号分隔或制表符分隔的文件的库)。
警告
不要自己解析逗号分隔的文件。 你会把一些特殊情况搞砸的!
如果文件没有头部(意味着你可能想把每一行作为一个列表,这带来的麻烦是你需要知道每一列是什么),你可以使用 csv.reader 对行进行迭代,每一行都会被处理成恰当划分的列表。
例如,如果有这样一个用 tab 划分的股票价格文件:
我们可以用下面的程序块来处理:
如果文件存在头部:
你既可以利用对 read.next() 的初始调用跳过头部的行,也可以利用 csv.DictReader 把每一行读成字典(把头部作为关键字):
即使你的文件缺少头部,你仍可以通过把关键字作为文件名参数传输来使用 DictReader。
同样,你可以用 csv.writer 来写限制的文件:
如果行中的各字段本身包含逗号,csv.writer 可以正确处理。但你自己手动写成的则很可能不会正确处理。比如,如果你尝试这样做:
你最终会得到像下面这样一个csv文件,它看起来像这样:
没人能看懂它的意思。
9.3 网络抓取
另一种获取数据的方法是从网页抓取数据。事实证明,获取网页很容易;但从网页上抓取有意义的结构化信息就不那么容易了。
9.3.1 HTML和解析方法
网络上的页面是由 HTML 写成的,其中文本被(理想化地)标记为元素和它们的属性:
在理想的情况下,所有的网页按语义标记,这对我们很方便,我们可以使用类似这样的规则来提取数据:找到 id 是 subject 的 <p> 元素并返回它所包含的文本。但在真实的世界中,HTML 并不总是具有很好的格式的,更不用说注解了。这意味着如果我们想搞清其含义,需要一些帮助。
为 了 从 HTML 里 得 到 数 据, 我 们 需 要 使 用 BeatifulSoup 库,它对来自网页的多种元素建立了树结构,并提供了简单的接口来获取它们。本书写作时,最新的版本是 Beatiful Soup 4.6.0,我们即将用到的就是这个版本。我们也会用到 requests 库,它与内置在 Python 中的其他方法相比,是一种发起HTTP 请求的更好的方式。
Python 内置的 HTML 解析器是有点严格的,这意味着它并不总是能处理那些没有很好地格式化的 HTML。因此,我们需要使用另外一种解析器,它需要先安装:
确保你处于正确的虚拟环境中,安装库:
为了使用 Beatiful Soup,我们要把一些 HTML 传递给 BeautifulSoup() 函数。在我们的例子中,这些 HTML 是对 requests.get 进行调用的结果:
完成这个步骤之后,我们可以用一些简单的方法得到完美的解析。
通常我们会处理一些 Tag 对象,它们对应于 HTML 页面结构的标签表示。
比如,找到你能用的第一个 <p> 标签(及其内容):
可以对 Tag 使用它的 text 属性来得到文本内容:
另外可以把标签当作字典来提取其属性:
可以一次得到多个标签:
通常你会想通过一个类(class)来找到标签:
此外,可以把这些方法组合起来运用更复杂的逻辑。比如,如果想找出包含在一个 <div>元素中的每一个 <span> 元素,可以这么做:
仅仅上述几个特性就可以帮助我们做很多事。如果你需要做更复杂的事情(或仅仅是出于好奇),那就去查看文档吧。
当然,无论多重要的数据,通常也不会标记成。你需要仔细检查源HTML,通过你选择的逻辑进行推理,并多考虑边界情况来确保数据的正确性。接下来我们看一个例子。
9.3.2 例:密切关注国会
数据科学公司的政策副总裁担心对数据科学行业的潜在监管,并要求你量化国会对这个话题的看法。他特别希望你能找到所有有发布“数据”新闻稿的代表。
在发布时,有一个页面有所有代表网站的链接
如果你“查看来源”,所有网站的链接看起来都像:
让我们从收集从该页面链接到的所有URL开始:
这将返回太多的URL。如果你看它们,我们从http://或者https://开始,中间是某种名字,并以 .house.gov 或者 .house.gov/. 结束。
这是一个使用正则表达式的好地方:
这仍然太多,因为只有435名代表。如果你看一下清单,有很多重复。我们可以用set来克服这些问题:
总是有几个众议院的座位空着,或者可能有一些没有网站的代表。无论如何,这已经足够好了。当我们查看这些网站时,大多数网站都有新闻稿的链接。例如:
请注意,这是一个相对链接,这意味着我们需要记住原始站点。让我们来抓取一下:
注意
通常情况下,像这样随意地爬一个网站是不礼貌的。 大多数网站都会有一个robots.txt文件,该文件表明你可以频繁地抓取站点(以及你不应该抓取哪些路径),但由于这是国会,我们不需要特别礼貌。
如果你通过滚动来查看它们,你将会看到大量/媒体/新闻稿和媒体中心/新闻稿,以及各种其他地址。其中一个URL是https://jayapal.house.gov/media/press-releases.
记住,我们的目标是找出哪些国会议员提到“数据”。“我们会写一个稍微更通用的功能,检查一页新闻稿中是否提到任何给定的术语。
如果你访问该网站并查看源代码,似乎在<p>标签中有来自每个新闻稿的片段,因此我们将使用它作为我们的第一次尝试:
让我们为它写一个快速测试:
最后我们准备找到相关国会议员,并告知他们的姓名给政策副总裁:
当我运行这个时,我得到了大约20名代表的名单。你的结果可能会不同。
注意
如果你查看不同的“新闻稿”页面,它们中的大多数都是分页的,每页只有5或10个新闻稿。 这意味着我们只检索了每位国会议员最近的几份新闻稿。 一个更彻底的解决方案将在页面上迭代并检索每个新闻稿的全文。
9.4 使用API
许多网站和网络服务提供相应的应用程序接口(Application Programming Interface,APIS),允许你明确地请求结构化格式的数据。这省去了你不得不抓取数据的麻烦!
9.4.1 JSON(和XML)
因为 HTTP 是一种转换文本的协议,你通过网络 API 请求的数据需要序列化(serialized)地 转 换 为 字 符 串 格 式。通 常 这 种 串 行 化 使 用JavaScript 对 象 符 号(JavaScript Object Notation,JSON)。JavaScript 对象看起来和 Python 的字典很像,使得字符串表达非常容易解释:
我们可以使用 Python 的 json 模块来解析 JSON。尤其是,我们会用到它的 loads 函数,这个函数可以把一个代表JSON对象的字符串反序列化(deserialize)为 Python 对象:
有时候 API 的提供者可能会不那么友好,只给你提供 XML 格式的响应:
我们也可以仿照从 HTML 获取数据的方式,用 BeautifulSoup 从 XML 中获取数据;更多细节可查阅文档。
9.4.2 使用无验证的API
现在大多数的 API 要求你在使用之前先验证身份。而若我们不愿勉强自己屈就这种政策,API 会给出许多其他的陈词滥调来阻止我们的浏览。因此,先来看一下 GitHub 的API,利用它我们可以做一些简单的无需验证的事情:
此处 repos 是一个 Python 字典的列表,其中每一个字典表示我的 GitHub 账户的一个代码仓库。(可以随意替换成你的用户名,以获取你的代码仓库的数据。你有 GitHub 账号,对吧?)
我们可以使用它来找出一周中最有可能创建哪些月份和天数的存储库。唯一的问题是,响应中的日期是字符串:
Python 本身没有很强大的日期解析器,所以我们需要安装一个:
其中你需要的可能只是 dateutil.parser.parse 函数:
类似地,你可以获取我最后五个代码仓库所用的语言:
通常我们无需在“做出请求而且自己解析响应”这种低层次上使用 API。使用 Python 的好处之一是已经有人建好了库,方便你访问你感兴趣的几乎所有 API。这些库可以把事情做好,为你省下查找 API 访问的诸多冗长细节的麻烦。(如果这些库不能很好地完成任务,或者它们依赖的是对应的 API 已失效的版本,那就会给你带来巨大的麻烦。)
尽管如此,偶尔你还是需要操作你自己的 API 访问库(或者,更常见的,去调试别人不能顺利操作的库),所以了解一些细节是很有好处的。
9.4.3 寻找API
如果你需要一个特定网站的数据,可以查看它的开发者部分或 API 部分的细节,然后以关键词“python <站点名> api”在网络上搜索相应的库。
有Yelp API、Instagram API、Spotify API等库。
如果你想查看有 Python 封装的 API 列表,那么在GitHub上有一个来自Real Python的不错的API列表(https://github.com/realpython/list-of-python-api-wrappers)。
如果最终还是找不到你需要的 API,还是可以通过抓取获得的。这是数据科学家最后的绝招。
9.5 案例:使用Twitter API
Twitter 是一个非常好的数据源。你可以从它得到实时的新闻,可以用它来判断对当前事件的反应,可以利用它找到与特定主题有关的链接。使用 Twitter 可以做几乎任何你能想到的事,只要你能获得它的数据。可以通过它的 API 来获得数据。
为了和 Twitter API 互动,我们需要使用 Twython 库(python -m pip install twython)。实际上有很多 Python Twitter 的库,但这一个是我用过的库中最好用的一个。你也可以尝试一下其他的库。
获取凭据
为了使用 Twitter 的 API,需要先获取一些证明文件(为此你无论如何都要有一个 Twitter的账户,这样你就能成为一个活跃友好的 Twitter #datascience 社区的一部分)。
注意
就像那些所有我不能控制的网站的指令一样,它们会在某个时刻过时,但是现在还是能发挥一段时间的作用的。(尽管在我写作本书的这段时间里,它们至少已经变更过一次了,所以祝你好运!)
以下是步骤:
1. 找到链接 https://apps.twitter.com/。
2. 如果你还没有注册,点击“注册”,并输入你的 Twitter 用户名和密码。
3.单击Apply申请开发人员帐户。
4.请求访问以供你自己使用。
5.填写申请书。它需要填写300字(真的)说明清楚你为什么需要访问数据,所以为了通过审核,你可以告诉他们这本书以及你有多喜欢它。
6.等一段不确定的时间。
7.如果你认识在Twitter上工作的人,给他们发邮件,问他们是否可以加快你的申请。否则,请继续等待。
8.获得批准后,请返回到developer.twitter.com,找到“应用程序”部分,然后单击“创建应用程序。”
9.填写所有必需的字段(同样,如果描述需要额外的字符,你可以讨论这本书以及如何找到它)。
10.单击“创建”。
现在你的应用程序应该有一个“键和令牌”选项卡,其中包含“消费者API公钥”部分,其中列出了“API公钥”和“API密钥”。“注意这些键;你需要它们。(而且,对他们保密!它们就像是密码一样。)
小心
不要分享它们,不要把它们印在书里,也不要把它们记录在 GitHub 公共代码库里。一种简单的方法是把它们存储在不会被签入(checked in)的 credentials.json文件里,而且可以使用 json.loads 取回它们。另一个解决方案是将它们存储在环境变量中,并使用os.environ检索它们。
使用Twython
使用Twitter API最棘手的部分是认证。(事实上,这是使用大量API最棘手的部分。) API提供者希望确保你被授权访问他们的数据,并且你不会超过他们的使用限制。他们还想知道谁在访问他们的数据。
身份验证有点令人痛苦。有一个简单的方法,OAuth 2,当你只想做简单的搜索时就足够了。还有一种复杂的方式,OAuth 1,当你想要执行操作(例如推特)或(特别是对我们)连接到推特流时,这是必需的。
所以我们坚持了更复杂的方式,我们将尽可能多地实现自动化。
首先,你需要API公钥和API密钥(有时分别称为消费公钥和消费密钥)。我可以从环境变量中获得,如果你愿意的话,你可以随时替换它们:
现在我们可以实例化客户端:
提示
在这一点上,你可能想考虑把ACCESS_TOKEN和ACCESS_TOKEN_SECRET保存在安全的地方,这样下一次你就不用经历这严格的过程了。
一旦我们有了一个经过验证的Twython实例,我们就可以开始执行搜索:
如果你运行上面这个,你应该得到一些推文,比如:
这并不那么有趣,主要是因为Twitter搜索API只是向你显示了一些最近的结果。当你在做数据科学时,你经常想要很多推文。这就是流媒体API有用的地方。它允许你连接到一个伟大的Twitter“消防水管”。若要使用它,你需要使用访问令牌进行身份验证。
为了使用Twython访问流API,我们需要定义一个从TwythonStreamer继承并覆盖它的on_success方法,也可能是它的on_error方法:
MyStreamer 会连接到 Twitter 流并等待 Twitter 给它发送数据。它每收到一些数据(在这里,一条推文表示为一个 Python 对象)就传递给 on_success 方法,如果推文是英文的,这个方法会把推文附加到 tweets 列表中,在收集到 1000 条推文后会断开和流的连接。
剩下的工作就是初始化和启动运行了:
它会一直运行下去直到收集 1000条推文为止(或直到遇到一个错误为止),此时就可以着手分析这些推文了。比如,你可以用下面的方法寻找最常见的标签:
每条推文都包含许多数据。你可以自己尝试一下各种方法,或仔细查阅 Twitter API 的文档。
注意
在一个正式的项目中,你可能并不想依赖内存中的列表来存储推文。相反,你可能想把推文保存在文件或者数据库中,这样就可以永久地拥有它们。
9.6 延伸学习
• pandas是数据科学用来处理(特别是导入)数据的一个主要的库。
• Scrapy是一个功能很健全的库,可用来构建更复杂的网络抓取器,来执行类似跟踪未知链接等任务。
• Kaggle拥有大量数据集。
XML是EXtensible Markup Language的缩写
XML是一种类似于HTML的标记语言
XML是用来描述数据的
XML的标记不是在XML中预定义的,你必须定义自己的标记
XML使用文档类型定义(DTD)或者模式(Schema)来描述数据
XML使用DTD或者Schema后就是自描述的语言
XML和HTML的主要区别是什么
XML是用来存放数据的
XML不是HTML的替代品,XML和HTML是两种不同用途的语言。
XML是被设计用来描述数据的,重点是:什么是数据,如何存放数据。
HTML是被设计用来显示数据的,重点是:显示数据以及如何显示数据更好上面。
HTML是与显示信息相关的, XML则是与描述信息相关的。
“XML”是用于网络上数据交换的语言,具有与描述Web页面的“HTML”语言相似的格式。该语言有“可以利用Web浏览器进行数据确认”以及“易于生成数据”等优点,因此主要用于在企业之间,或者在企业内部更加方便地进行数据交换和利用。首先为了便于理解,下面假设有这么一种情况:某图书销售商要着手建立自己的站点,并发送书店里的品种目录和库存情况等信息。
管理图书时,需要使用TABLE标签等,以一览表的形式提供 “书名”、“发行日期”、“库存”、“作者”、“出版社”和“定价”等数据。以这种形式汇总数据后,如果是人,就能够迅速地了解到各自所需的内容。但是,计算机(或系统)即使能够理解页面结构或数据布局,也无法理解这里的数据是什么意义(属性)。
然而,“XML”则正是能够让计算机也理解这些数据属性的技术。
如果使用XML,比如“库存目前有多少?”以及“某个作家写的书卖了多少册?”等数据就能够由计算机“自动地”掌握,并能够将这些数据与交易对象“共享”。这样一来,出版社就能够在制定今后的出版计划时参考这些数据,而且销售公司制定有效的配送计划时也将更加容易。这就必定大大有助于削减人事成本,以及提高管理效率。
当然,即便不使用XML,比如,如果能够建立一个规范的数据库,并为每个字段定义一个“书名”和“定价”等名称,计算机也能够理解。但是要想在Web上实现这一点,却要花费相当的人力和成本。在这一点上,如果是XML,由于“能够利用Web浏览器对数据进行确认“,因此只要拥有能够连接因特网的计算机和支持XML的浏览器,就不需再进行特别的投资。
使用XML,还能够将在以前的数据库中难以处理的数据转化成数据库。
XML的描述方式与HTML相同,利用被括号<>括起来的字符串进行描述。在HTML中,括号内所定义的都是版面(Layout)等信息。而XML则同时定义了数据的属性,比如刚才提到的图书,就是以<书名>、<作者>和<出版社>等方式定义。像这样的定义方式可以自由设置。因此,甚至有不少企业自己定义XML,然后将其用于本公司内部的数据交换。自由度如此之高也是XML受到极大关注的原因之一。
但是,企业之间的数据交换才是XML的着眼点之一。因此,各公司的定义如果不规范化就无法通用。目前,以微软为主的标准化团体“Biztalk.org”和民间团体“Rosetta Net”等都希望能针对各行业和领域制定“可以广泛利用的标志”,以减少定义XML的麻烦。
如果像上述所说的那样能够制定XML的标准,并被广泛应用,那么不止是企业之间的数据交换将变得更简单,而且语音数据和动态图像数据等在过去的数据库中难以进行处理的数据也必将能够轻松转化成数据库。这一点在管理方面也可以说是一个巨大的可取之处
xml即extensible markup language(可扩展标记语言)的缩写。
xml实际上是web上表示结构化信息的一种标准文本格式,它没有复杂的语法和包罗万象的数据定义。xml同html一样,都来自sgml(标准通用标记语言)。sgml是一种在web发明之前就早已存在的用标记来描述文档资料的通用语言。但sgml十分庞大且难于学习和使用。鉴于此,人们提出了html语言。但近年来,随着web应用的不断深入,html在需求广泛的应用
中已显得捉襟见肘,有人建议直接使用sgml作为web语言。但sgml太庞大了,学用两难尚且不说,就是全面实现sgml的浏览器也非常困难。于是web标准化组织w3c建议使用一种精简的sgml版本——xml。xml与sgml一样,是一个用来定义其他语言的元语言。与sgml相比,xml规范不到sgml规范的1/10,简单易懂,是一门既无标签集也无语法的新一代标记语言。
xml的先进特性
xml继承了sgml的许多特性,首先是可扩展性。xml允许使用者创建和使用他们自己的标记而不是html的有限词汇表。这一点至关重要,企业可以用xml为电子商务和供应链集成等应用定义自己的标记语言,甚至特定行业一起来定义该领域的特殊标记语言,作为该领域信息共享与数据交换的基础。
其次是灵活性。html很难进一步发展,就是因为它是格式、超文本和图形用户界面语义的混合,要同时发展这些混合在一起的功能是很困难的。而xml提供了一种结构化的数据表示方式,使得用户界面分离于结构化数据。所以,web用户所追求的许多先进功能在xml环境下更容易实现。
第三是自描述性。xml文档通常包含一个文档类型声明,因而xml文档是自描述的。不仅人能读懂xml文档,计算机也能处理。xml表示数据的方式真正做到了独立于应用系统,并且数据能够重用。xml文档被看作是文档的数据库化和数据的文档化。
除了上述先进特性以外,xml还具有简明性。它只有sgml约20%的复杂性,但却具有sgml功能的约80%。xml比完整的sgml简单得多,易学、易用并且易实现。另外,xml也吸收了人们多年来在web上使用html的经验。xml支持世界上几乎所有的主要语言,并且不同语言的文本可以在同一文档中混合使用,应用xml的软件能处理这些语言的任何组合。所有这一切将使xml成为数据表示的一个开放标准,这种数据表示独立于机器平台、供应商以及编程语言。它将为网络计算注入新的活力,并为信息技术带来新的机遇。目前,许多大公司和开发人员已经开始使用xml,包括b2b在内的许多优秀应用已经证实了xml将会改变今后创建应用程序的方式。
从1998年开始, xml 被引入许多网络协议,以便于为二个软件提供相互通信的标准方法。简单对象访问协议(soap)和 xml- rpc规范为软件交互提供了独立于平台的方式,从而为分布式计算环境打开了大门。几乎所有主要的软件厂商都支持soap。soap的快速成功史无前例地提高了软件的互操作潜力。当今,web服务革命正在兴起,而soap正是其基础协议。
HTML是超文本标记语言
XML是可扩展文本标记语言
大数据如何分析报告
方法/步骤1进行大数据分析之前,首先要梳理清楚分析的对象和预期目标,不能无的放矢。
2接下来,就是进行相关数据的采集,通过各种渠道和接口获取,将数据集中起来。
3直接采脚境钟异式也临顶集到的数据,大部分情况下是杂乱无章的,这时候就要进行数据清洗。
4将数据按照一定的规则进行分类,使数据变得相对有序,便于后续的各种分析。
5基于各种成熟的分析工具或者算省兵远等型白法,对数据进行分析,获取相关趋势性结论。
6大数据分析报告的编写,就是在数据初步分析基础上进行整理汇总,阐述观点。
7如果仅仅是基于历史数据的分析来自,其结论可能存在一定的偏离,因此,最好能通过持续的采集更新数据并分析以提升准确性。