第 1 章:你需要知道的编程语言

无论我们谈论的是 Facebook 帖子、推文还是 Yelp 评论,我们都需要了解在线平台的结构,以便从中提取信息。为此,我们需要学习编码和网络开发的基础知识。

本章概述了 Web 与 Web 语言以及在我们的数据挖掘工作的上下文中是如何工作的。了解数据库和网页如何交互将有助于我们调查在线可用的社交媒体数据类型以及我们如何收集这些数据。

那么我们应该从哪里开始呢?对于初学者来说,编码环境肯定有点令人生畏(这对我来说绝对是!)。这是一个充满首字母缩略词的世界,技术术语和多种编程语言。浏览所有这些语言可能会让人不知所措,所以首先让我们缩小并看看它们所扮演的角色。

前端语言

Web 语言可以大致分为两类:前端语言和后端语言。我们将通过讨论 Web 浏览器用来读取、解释和呈现我们在浏览器窗口和网站选项卡上看到的视觉元素的三种前端语言来开始本章:HTML, CSS, 和 JavaScript,这些语言对我们来说很重要,因为它们包含我们想要从社交媒体网站挖掘的内容。

我们将在本章的后半部分介绍后端语言,它们与服务器、数据库和数据流进行通信。当我们想通过直接连接到存储数据的计算机来收集社交媒体数据时,它们就会发挥作用。

HTML 原理

我们希望在网站上收集生活的大部分社交媒体内容,而网站由超文本标记语言 (HTML) 组成。 HTML 构建构成网站内容的文本和图像,以便浏览器可以呈现或显示,供用户查看的内容。 HTML 代码本身只是一个文本文件,但是当在浏览器中打开 HTML 文件时,它会告诉浏览器将内容格式化并显示为网页。

网页由以 .html 扩展名结尾的文件组成。大多数网站的主页是 index.html,因此这是我们的浏览器在访问网站时通常会查找的文件。这些文件通常存在于服务器上,这就像计算机上的硬盘驱动器,它始终处于开机状态,其他计算机可以通过 Internet 访问。统一资源定位符 (URL) 有点像服务器上文件夹的地址。

当我们的浏览器访问一个 URL 时,它们会下载代码行,然后以可视化的形式解释和呈现这些代码行。一个简单的网站可以只包含一行代码,如图所示:

一个简单的网页 图 1-1 一个简单的网页

该网站的底层代码如下所示:

<p> ohai there! </p>

在这种情况下,内容是句子 ohai there!。围绕内容的两段文本称为 HTML 标记。

标签是文本和尖括号 (<>) 的组合,告诉浏览器应该如何组织每种类型的内容。例如,代码示例中的 标签告诉浏览器句子是一个段落。标签还可以告诉浏览器内容是标题、图像还是其他类型的内容。标签和标签的内容一起称为元素。每个元素通常以开始或开始标签开头,例如 ,并以结束标签或结束标签结束,这与开始标签相同,但在第一个括号后有一个反斜杠,例如 。开始和结束标签包含将在网站上呈现的内容。某些元素,例如 ``,称为空元素,不需要结束标记。

一个 HTML 段落元素 图 1-2 一个 HTML 段落元素

当上图中的元素在浏览器中呈现时,它看起来像下图:

段落元素在浏览器中打开时的外观 图1-3 段落元素在浏览器中打开时的外观

总而言之,HTML 标签是一种告诉浏览器如何构建内容的方式,而标签之间的信息则告诉浏览器应该在网站上呈现哪些内容。

HTML 元素也可以嵌套,这意味着一个标签包含一个或多个其他标签及其内容。此功能通常用于聚类相关元素。例如,标题和段落可以嵌套在 div 元素中,它定义了一个部门。嵌套元素表示 div 元素内的标题和段落属于一起。为了显示嵌套,您通常使用缩进——即在一行代码前添加空格或制表符——这是可选的,但使代码更清晰。

例如,我们可以将图 1-1 中的段落元素放入 `` 标签中,如下所示:

<div>
    <p>This is a paragraph full of great information!</p>
</div>

整个段落元素现在包含在开始和结束 标签中。为了显示段落元素是嵌套的,我们还将它放在与 标签分开的一行上,并将该行缩进四个空格。在浏览器中呈现时,嵌套的段落元素应如图所示:

在浏览器中呈现的 div 和嵌套段落元素 图 1-4 在浏览器中呈现的 div 和嵌套段落元素

HTML 会忽略缩进,并且 div 元素在呈现时是不可见的。这意味着浏览器仅呈现段落标签内的内容,并且该元素看起来与图 1-3 中的相同。

尽管您实际上无法在浏览器中看到 div 元素和其他不可见的 HTML 结构,但它们很有用,因为它们将网站组织成块。例如,想想构成推文的许多部分。每条推文都包含发布者的 Twitter 信息(他们的用户名、Twitter 用户名和 Twitter 个人资料照片),时间戳、推文文本、推文的转发次数和收藏夹数量。这些部分都聚集在嵌套的 HTML 标签中。嵌套可以变得相当复杂,取决于网站的复杂程度以及彼此相关的元素数量。一些嵌套元素甚至可能进一步嵌套在其他元素中!

当您从网站中挖掘信息时,了解内容在 HTML 元素中的结构以及您要查找的特定信息所在的位置会很有帮助。稍后我们将重新讨论如何导航嵌套元素以检查推文的 HTML 结构。不过,首先我们需要谈谈 CSS,它与 HTML 紧密相连。

CSS 原理

到目前为止,我们所有的示例都只是纯文本,但网站通常由更多内容组成。例如,推文文本的字体、颜色和大小可能与显示推文发布日期和时间的文本不同。您可能想知道浏览器如何知道以不同的颜色、字体和大小呈现 HTML。这就是级联样式表 (CSS) 的用武之地。

CSS 赋予 HTML 文件颜色、功能和(有些人甚至可能说)字符!CSS 是允许我们为不同类型的 HTML 内容分配特定外观的语言。您可以将 CSS 视为一组视觉指南,它告诉浏览器每个 HTML 元素在网页上的外观。

例如,只有通过 CSS,您的页面才能从图 1-4 变为图 1-5。

图 1-5:在浏览器中呈现的 div 和段落元素,使用 CSS 格式

在社交媒体数据领域,CSS 通常用于确保以一致的方式呈现元素类型。例如,在推文的时间线上,每个推文时间戳都需要以相同的字体、颜色和大小呈现。

有多种方法可以将 CSS 样式分配给 HTML 标签。一种方法是通过内联 CSS,它在创建 HTML 标记的同一行中分配 CSS。您可以在清单 1-1 中看到一个示例。

<div ①style="②color: #272727;">
    <p>This is a paragraph full of great information!</p>
</div>

清单 1-1:使用内联 CSS 格式化 HTML

在本例中,一个属性被添加到div元素的开始标记中。属性是与每个HTML标记关联的附加信息。属性名称位于开始角括号之前。名称后面跟一个等号(=),然后是属性的内容,该内容包含在双引号之间(尽管HTML也接受单引号)。属性通常是属于它们所在的标记的特征。属性被传递给嵌套的HTML元素。在本例中,div元素有一个style属性① 其中我们添加了内联CSS,这意味着现在标记中的任何内容都必须遵循style属性中定义的CSS样式规则。由于段落元素嵌套在div元素中,因此段落元素及其内容继承指定给div的任何样式。

CSS使用属性来更改我们可以在网站上使用的颜色、字体和其他格式选项。属性类似于HTML属性,但格式为冒号(:),将属性名称与属性值分隔开。例如,“样式”属性中有“颜色”属性②, 这决定了我们字体的颜色。网站使用十六进制颜色(有关教程,请参见 https://www.w3schools.com/colors/ ),将颜色表示为六个数字和字母的组合。在本例中,#272727 表示深灰色。

将CSS添加到HTML的另一种方法是在内部样式表中编写样式规则。样式表是内部的,因为CSS直接插入到样式标记之间的HTML代码中,但不与它格式化的标记内联。

当您使用内部样式表查看网站时,您会在其中找到类和ID

清单1-2显示了一个内部样式表的示例,它定义了如何设置类和ID的样式。

<style>
.my_styles①{
    color: #272727;
    font-size: 16px;
    font-weight: 600;
    text-shadow: 2px 2px #d8d8d8;
}
#my_div②{
    font-family: "Proxima Nova", Helvetica, sans-serif;
}
</style>
<div class="my_styles" id="my_div">③
    <p>This is a paragraph full of great information!</p>
</div>

清单1-2:使用内部样式表将CSS样式分配给HTML

每个样式规则位于标记之间。第一组样式规则位于类内部,该类以句点(.)开头① 和类的名称。在本例中,该类是my_styles(请注意,名称中没有空格)。类名后面跟着两个大括号({ }), 其中包含类的样式规则。在本例中,您可以看到我们的CSS为my_styles类应用到的任何元素指定了颜色、字体大小、字体重量和文本阴影。示例中显示的下一个规则创建了一个ID,我们称之为my_div②. ID由紧跟ID名称的哈希标记表示。ID的样式规则也包含在大括号之间。内部样式表以结束标记结尾。

尽管CSS样式规则是在这个HTML中定义的,但这并不意味着它们已经应用于任何HTML元素。为了格式化HTML元素,您需要将类或ID分配给标记。

为此,我们将“my_styles”类和“my_div”ID分配给标记的class和ID属性③. 这意味着div元素中的任何内容现在都将根据my_styles类和my_div ID规则设置样式。

图1-6显示了CSS和HTML创建的外观。

图 1-6:应用于清单 1-2 中嵌套 div 元素的内联 CSS 样式表

通常,开发人员在设计网站时会编写数百(如果不是数千)行 CSS。当样式规则变得复杂和丰富时,开发人员通常会将它们放入一个单独的文档中,称为样式表,他们通过一个外部链接标签加载到他们的 HTML 页面中,如下所示:

<link rel="stylesheet" type="text/css" href="css/mystyle.css">

CSS 样式表使用 .css 扩展名保存并存储在服务器上。外部样式表的格式与内部样式表的格式相同,只是您不需要 HTML

这是关于使网站看起来漂亮的很多信息。它现在似乎与我们的目的无关,但 CSS 很重要,因为它可以帮助我们了解网页设计师如何在网站上构建重复元素。例如,如果设计师使用一个类以特定方式为 Facebook 帖子的所有标题设置样式,我们将更容易找到包含标题的每个 HTML 元素。

现在您已经了解了网站设计和结构的基础知识,让我们看一个来自 Twitter 的示例,该示例展示了 HTML 和 CSS 的实际应用。

推文在 HTML 和 CSS 中的结构

图 1-7:Twitter 时间线上显示的推文示例

时间线上的每一项都代表一条推文,每条推文都有一个附加的信息子集。而且,正如您现在可能已经收集到的,每条推文都是使用 HTML 和 CSS 呈现和组织的。

虽然浏览器可以为用户呈现整洁的视觉效果,但这个网站的作用远比我们最初想象的要大。让我们看看引擎盖下的tweet代码行是什么样子。要做到这一点,我们需要打开一个漂亮的小浏览器功能,称为开发者工具。这些工具内置于某些浏览器(如Chrome)中,并可作为插件用于其他浏览器(如Firefox)。我们将使用Chrome浏览本书的示例,Chrome是一款免费浏览器,您可以从中下载 https://www.google.com/chrome/.

使用 Google Chrome,转到Twitter时间线并单击一条推文。要在Chrome中访问tweet的HTML,请从Chrome的菜单中选择View>Developer>Developer Tools,或在Windows中按ctrl-shift-I或在Mac上按command-option-I。

这将在浏览器中打开第二个视图,称为Web Inspector。Web检查器允许您查看网站底层的代码,如图1-8所示。

图 1-8:在 Web Inspector 中打开的推文

将鼠标逐行移到代码上。当你这样做的时候,Chrome应该突出显示网页中与你鼠标悬停的代码相对应的部分。通过单击HTML标记左侧的小三角形,可以展开或折叠嵌套的HTML。你鼠标滑过的前几个标签可能会突出显示整个网站,但出于我们的目的,我们只想看到组成一条推文的代码。当你自己做这件事时,你需要深入到每个嵌套的标签,直到Chrome只突出显示你正在寻找的网站的部分。对于大型和复杂的网站,此过程可能需要一段时间。

对于这个例子,我们将直接跳到我们正在寻找的内容。在Web检查器内单击(不在网页上!),然后在Windows上按ctrl-F,或在Mac上按command-F。“检查器”窗口中应显示一个搜索栏。在搜索栏中输入permalink container,然后按Enter键。您应该被带到一个只突出显示一条tweet的div类。

现在,您可以看到tweet由嵌套在标记中的一组代码组成,该标记已分配给类permalink容器。请注意,这段代码由标记和类组成,就像我们到目前为止介绍的简单HTML示例一样。虽然真实的网站数据看起来很复杂,但信息嵌入到标记中,就像它嵌入到更简单的HTML代码中一样。

让我们更仔细地看看tweet代码。有很多信息,但别担心!我们将把它分解,一次只看一部分。清单1-3显示了图1-8中推文的浓缩版本(因为每条推文可能有600多行代码!)。

①<div class="permalink-container permalink-container--withArrows">
    <div role="main" class="permalink light-inline-actions  stream-uncapped original-permalink-page">
        <div class="permalink-inner permalink-tweet-container">
            ②<div class="tweet permalink-tweet js-actionable-user js-actionable-tweet js-original-tweet has-cards with-social-proof has-content logged-in no-replies js-initial-focus focus" data-associated-tweet-id="920092249765175296" data-tweet-id="920092249765175296" data-item-id="920092249765175296" ③data-permalink-path="/BuzzFeed/status/920092249765175296" data-conversation-id="920092249765175296" data-tweet-nonce="920092249765175296-f30dd53d-6fe8-4553-9224-69186d43d82c" data-tweet-stat-initialized="true" data-screen-name="BuzzFeed" data-name="BuzzFeed" data-user-id="5695632" data-you-follow="true" data-follows-you="false" data-you-block="false" data-reply-to-users-json="[{"id_str":"5695632","screen_name":"BuzzFeed","name":"BuzzFeed","emojified_name":{"text":"BuzzFeed","emojified_text_as_html":"BuzzFeed"}}]" data-disclosure-type="" data-has-cards="true" tabindex="0">
                <div class="content clearfix">
                    <div class="permalink-header">
                        <a class="account-group js-account-group js-action-profile js-user-profile-link js-nav" href="/BuzzFeed" data-user-id="5695632">
                            <img class="avatar js-action-profile-avatar" src="https://pbs.twimg.com/profile_images/687767655214891008/n9pHVYUl_bigger.png" alt="">
                            <span class="FullNameGroup">
      ④<strong class="fullname show-popup-with-id " data-aria-label-part="">BuzzFeed</strong><span>‏</span>
--snip--
</div>

清单 1-3:组成一条推文的 HTML

Twitter 上的每条推文都以这样的结构存在,在本书结束时,您将能够使用代码从成百上千的这些结构中自动提取您需要的信息。此示例中的 HTML 乍一看很复杂且令人困惑,但您可以通过逐个查看它来理解它。

例如,具有 permalink-container 类的 标记是包含整个推文①的 HTML 标记。嵌套在该标签中的是一个 类,其中包含推文 ② 和一些与推文相关但未显示的信息。其中一些信息标有易于理解的名称,例如 data-follows-you,它告诉浏览器该推文的所有者是否正在关注您的 Twitter 帐户。其他信息,如 data-permalink-path ③,有一个不透明的名称,你需要通过一些侦探工作来弄清楚。在这种情况下,数据永久链接路径是推文 https://twitter.com/ URL 末尾的链接。在这段代码片段的末尾是一个标记,它使文本变粗,被分配了类全名④。标签的内容是 Twitter 帐户名称 BuzzFeed。

虽然代码最初看起来势不可挡,但通过仔细梳理,我们发现了与推文相关的重要信息。我们将从社交媒体中挖掘的大部分数据也是如此。

JavaScript 的工作原理

HTML 和 CSS 与我们的数据收集直接相关,因为它们与我们有兴趣获取的社交媒体内容密切相关,但网站中还涉及一些其他活动部分,例如 JavaScript。

JavaScript 是一种为网站带来交互性的编程语言,可以操作页面上呈现的元素。它允许我们在网站呈现之前甚至之后动态更改网站。换句话说,使用 JavaScript,我们可以更改 HTML 和 CSS 的属性或属性,甚至可以在页面上创建 HTML 元素。

让我们通过使用 JavaScript 更改清单 1-4 中段落的颜色来看看这是如何工作的。

<div class="my_styles" id="my_box">
    <p>This is a paragraph full of great information!</p>
</div>

示例 1-4:嵌套在 div 中的段落

在浏览器中,此代码将呈现为图 1-9。

图 1-9:应用了一些样式的段落

清单 1-4 中的代码包含一个 标签,该标签被分配了一个名为 my_styles 的类和一个名为 my_box 的 ID。 使用 JavaScript,我们可以使用段落的类或 ID 来选择段落的 HTML 标签。 一旦我们有了标签的类或 ID,我们就可以使用 JavaScript 为标签分配一个新的类或新的样式。

让我们向清单 1-4 中的代码添加一些 JavaScript,使用 ID my_box 选择我们的 HTML 元素,如清单 1-5 所示。

① <div class="my_styles" id="my_box">
    <p>This is a paragraph full of great information!</p>
</div>
② <script type="text/javascript">
        ③document.getElementById("my_box").style.color = "red"
</script>

示例 1-5:使用 JavaScript 通过 ID 选择元素并修改其颜色

JavaScript 必须介于两者之间

虽然您可能不知道如何阅读 JavaScript,但您通常可以通过阅读来解读相当多的内容。 让我们尝试一次一个地遍历 ③ 处的 JavaScript。 首先,我们正在浏览文档。 然后我们使用了 JavaScript 的一部分,称为 getElementById(),它会告诉你它到底做了什么——它根据它的 ID 获取一个元素! 在许多编程语言中,当代码带有括号时,括号外的部分作用于括号内的内容。 在本例中,my_box 位于括号内,因此我们告诉 getElementById() 对 my_box 执行操作。 这会在①处抓取带有 my_box ID 的 div 元素。 然后,我们给刚刚抓取的 div 一个新的 CSS 样式和颜色。 在这种情况下,我们将应用样式“红色”。

通过这段 JavaScript,我们现在更改了在浏览器中呈现的文本颜色,如图 1-10 所示,其中较深的灰色代表红色文本颜色。

图 1-10:使用 JavaScript 应用于 div 的样式

这是 JavaScript 工作的基本方式。你不需要知道如何为本书编写 JavaScript,但你应该明白它是网页的一个非常重要的部分,它能够改变网站的内容,包括我们希望从社交媒体网站收集的内容.

后端语言

如您所见,当我们检查社交媒体网站的代码时,我们感兴趣的许多数据都显而易见,但还有其他获取数据的方法对日常用户而言是不可见的。这些方法是为程序员开发的,面向程序员,所以为了访问它们,你也需要成为一名程序员。为了做到这一点,你需要学习一种后端语言。

后端语言可以创建、更新存储在服务器上的数据库并与之通信。您可以将服务器视为通过 Internet 访问的硬盘驱动器:它是一个包含大量信息的大型物理驱动器,包括充满社交媒体数据的数据库以及构成我们访问的网站的所有 HTML 和 CSS 文件。可以在线查看。后端语言还允许您在计算机上创建文本文件或电子表格等文件,并将数据直接写入这些文件。

使用 Python

在本书中,我们将使用 Python 作为后端语言来收集和分析数据。 Python 是一种开源编程语言,这意味着它由一个活跃的社区开发,并提供给开发人员免费使用,甚至可以用于商业目的。它定期更新并有多个版本。我们将使用最新版本:Python 3.7。

本书中的课程并非旨在让您成为 Python 专家,而是帮助您了解基本的编码概念、语言的工作原理、如何阅读和理解现有脚本(包含代码的文本文件),以及如何根据自己的需要修改代码。换句话说,读完这本书后,你不会构建花哨的应用程序和用 Python 编写复杂的脚本,但你会知道足够“危险”并为自己的目的构建脚本。

无论您的机器上是否安装了 Python,您都应该通过 Python 的官方网站 (https://www.python.org/downloads/) 下载并安装最新版本的 Python 3。

Python 入门

为了将 Python 用于我们的目的,我们需要了解基本的编码概念,因此构建接下来的几个练习来向您介绍其中的几个。将每个练习视为词汇或语法课程,这将使您更接近编写完整的“句子”——在这种情况下,是一行 Python 代码。

对于这些练习,您需要将代码行输入到交互式 shell 中,这是一个可以阅读和理解 Python 的界面。首先,您需要打开命令行界面 (CLI),这是您计算机上允许您运行命令的程序。在 Mac 上,您将使用“应用程序”文件夹中的“终端”。在 Windows 上,您可以使用通过“开始”菜单提供的命令提示符。

打开您的 CLI 并在 Mac 上输入 python3 或在 Windows 上输入 python。这应该会打开您的交互式 shell。如果您看到提示,您就会知道您的交互式 shell 已打开,该提示看起来像三个尖括号 (»>),如图 1-11 所示。

图 1-11:通过 Mac 的内置 CLI 终端访问的交互式 shell

现在您的 CLI 窗口知道如何解释 Python 代码。首先输入以下简单命令并按回车键:

>>> print("hello!")

恭喜!您刚刚编写了第一行 Python。你告诉你的交互式 shell 打印出文本 hello!,它现在应该在你输入的命令之后显示出来,像这样:

>>> print("hello!")
hello!

您输入的命令称为打印语句,用于打印您在括号之间输入的引用文本。除了能够打印出文本之外,Python 还可以进行数学运算,所以让我们尝试一下。将此等式输入到您的交互式 shell 中:

>>> 5 + 4
9

Python 中,数学方程称为表达式,它是一行代码,允许我们使用运算符修改值。表达式是编程中最基本的概念之一:它们可以让您将这些数字之类的东西修改为不同的东西。

在这个例子中,我们取了两个值——5 和 4——并通过数学运算符修改它们,该运算符对值执行运算。在这种情况下,加号 (+) 是运算符。

每个值都有一个与之关联的类型,称为数据类型。数据类型是信息的类别。例如,数字可能是一种数据类型,而文本可能是另一种数据类型。 Python 对每种数据类型的处理方式不同,并非所有运算符都适用于所有数据类型,因此您需要能够区分它们。

您将在 Python 中使用多种数据类型,包括整数来表示整数,例如 1、2、3、4、5 等。您还将使用浮点数,它们是包含小数的数字,如 1.2 和 3.456。当您需要使用文本时,您将使用字符串,即“串”在一起的字符。字符串包含在双引号 (“) 或单引号 (‘) 之间。字符串可以包括字母字符、数字、空格和其他符号。例如,“Lam”、“Lam is a writer”和“123567”都是字符串。

使用数字

Python 提供了许多数学运算符。 正如您所见,有一个加号 (+),它将符号两侧的值相加,但您还会发现在学校使用过的其他数学运算。

例如,减号 - 从左侧的值中减去右侧的值:

>>> 2 - 1
1

除了加号和减号运算符之外,您还会发现一些使用不熟悉符号的熟悉运算符。例如,数学课中的乘法使用 × 乘法符号,但在 Python 中,您将使用星号 ( * ) 代替:

>>> 2 * 3
6

类似地,除法使用另一个不熟悉的符号,即正斜杠 (/),并产生一个浮点数:

>>> 6 / 4
1.5

Python 有几个其他的数字运算符,但现在让我们继续修改其他数据类型。

使用字符串

与其使用 Python 修改整数和浮点数,不如尝试修改一些字符串。转到您的交互式 shell 并输入:

>>> "Hello, my name is " + "Lam"
'Hello, my name is Lam'

好极了! 我们只是使用字符串连接运算符 (+) 将两个字符串合并为一个字符串。 串联是将事物组合在一起的行为。

尽管字符串连接运算符使用与加法运算符完全相同的符号来将数字相加,但它们是不同的,因为它们对不同的数据类型进行操作。

两个双引号或两个单引号之间的任何内容都是字符串,即使它看起来像另一种数据类型,如数字。 例如,如果我们将两个引号之间的数字添加到两个引号之间的另一个数字中,Python 将不会对它们执行数学运算,而是从它们创建一个新字符串:

>>> "5" + "4"
'54'

字符串“5”与整数 5 不同,“4”也是一个字符串。当这两个值用加号操作时,它们是连接而不是相加的。确保您对不同的数据类型有很好的掌握,因为如果使用不当,就会出错。例如,如果你试图在一个字符串和一个整数上使用加号,比如“5”+4,你会得到一个错误,因为 Python 不知道你使用的是加法运算符还是字符串连接操作员。

请注意,Python 接受单引号或双引号可互换地表示字符串,但请确保您保持一致:如果字符串以双引号开头,则必须以双引号结尾。单引号也是如此。一般来说,最好选择一种约定——双引号或单引号——并在整个脚本中坚持使用。

在变量中存储值

既然您已经了解了表达式如何让您修改值,我们将继续讨论另一个重要概念:变量。变量是存储整数、浮点数或字符串等值的一种方式。把一个变量想象成一个带标签的盒子。将值放入该框中后,您可以使用标签引用它们。您还可以更改框中的值并将其替换为其他值。将一段数据放入变量“框”中称为为变量赋值。

要创建变量,请为其命名。这个名字应该是描述性的,就像你给一个装满锅碗瓢盆的盒子贴上“厨房用具”而不是“东西”的标签一样。您几乎可以在 Python 中为变量命名任何名称,但名称不能有空格且不能已被使用。例如,您不能有两个完全相同名称的变量,并且您不能使用可能与其他 Python 代码混淆的名称,例如可能被误认为是整数的普通数字。

一旦确定了变量的名称,就可以使用赋值运算符(等号 (=))在其中存储值。

例如,要将字符串“Lam”分配给名为 name 的变量,请在交互式 shell 中输入名称、赋值运算符,然后输入要分配的值“Lam”,如下所示:

>>> name = "Lam"

您现在已经告诉交互式 shell,变量名称存储值“Lam”。 与我们之前的示例不同,您不应在此处获得任何输出。

要打印出存储在变量名中的值,请在 print() 命令中输入变量名而不是字符串值:

>>> print(name)
Lam

变量名称存储“Lam”,因此 print() 命令仅输出字符串值。

我们也可以使用变量代替表达式中的字符串值,如下面的代码所示:

>>> "My name is " + name
'My name is Lam'

Python 接受字符串“My name is”并将存储在 name 变量中的值连接到它。

我们还可以通过为变量分配不同的值来更改我们在变量中存储的内容。让我们看看这是如何一步一步地工作的:

>>> name = "Lam"
>>> "My name is " + name
'My name is Lam'
>>> name = "Rosa"
>>> "My name is " + name
'My name is Rosa'

在第一行,我们将字符串“Lam”分配给 name。 然后我们将其打印在一个表达式中,结果是字符串“My name is Lam”。 接下来,我们将值命名为“Rosa”,以便 Python 将新值存储在我们的变量中。 如果我们使用之前使用的相同 print() 命令,Python 将使用当前存储的值并打印“My name is Rosa”。

同样很棒的是,我们可以将数字存储在变量中并在其中执行数学运算:

>>> initial_age = 10
>>> time_passed = 20.5
>>> initial_age + time_passed
30.5

首先我们将整数 10 赋给 initial_age 变量。然后我们将浮点数 20.5 分配给 time_passed 变量。在第三行中,我们使用加号将分配给 initial_age 的值与分配给 time_passed 的值相加。由于我们将存储在变量 initial_age 和 time_passed 中的两个数值相加,结果是 30.5。

正如您在这些示例中所看到的,我们可以将不同类型的数据类型分配给一个变量——一个变量可以保存字符串、浮点数和整数。变量在从社交网络收集数据点或值方面发挥着重要作用。例如,我们可以从网站上收集每个数据点,将其临时存储在适当的变量中,然后将每个数据点写入电子表格。

在列表中存储多个值

除了存储一个值,一个变量还可以以列表的形式保存多个值。列表是一种 Python 数据类型,可以保存多种其他数据类型。要在 Python 中创建列表,请输入要存储在列表中的值,用逗号 (,) 分隔,并用两个方括号 ([ ]) 分隔。尝试在交互式 shell 中创建一个列表,如下所示:

>>> ["Lam", "Rosa"]
['Lam', 'Rosa']

您还可以通过为变量分配列表值来将列表存储在变量中,就像为它分配字符串值一样。在交互式 shell 中,创建一个列表,如下所示:

>>> names = ["Lam", "Rosa"]

要打印列表,请使用 print() 命令

>>> print(names)
['Lam', 'Rosa']

列表也是处理不同数据类型的好方法,比如整数和字符串的混合:

>>> numbers = [0, 2.6, 7]
>>> tweet_statistics = [536, 301, "New York"]

如您所见,第一个变量 numbers 存储整数和浮点数(0、2.6 和 7)列表,而第二个变量 tweet_statistics 存储整数列表(536 和 301)和字符串(“纽约”)。

当我们从社交网络收集不同类型的数据时,不同数据类型的列表非常有用。例如,我们可能希望将收藏推文的人的 Twitter 句柄存储为列表。我们还可以将与推文相关的统计信息存储在列表中。例如,存储在变量 tweet_statistics 中的值列表可以表示与推文相关的收藏数量(536)、转发数量(301)和位置(“纽约”)。

无论我们查看哪种类型的数据,列表都可能是我们用来存储数据的一种方式。当我们开始收集数据时,熟悉列表可以极大地帮助我们。

使用函数

在前面的练习中,我们了解到 Python 具有变革性的力量。通过表达式,我们可以访问和修改数据。这本身就非常强大,但更强大的是 Python 能够比人类更快地重复操作。

想象一下,尝试计算 Facebook 页面发布的帖子数量。手动计算单个页面的每个帖子是一回事,但想象一下,必须计算 10、100 甚至 1,000 个 Facebook 页面发布的帖子总数——这可能需要数小时、数天甚至数周!如果您要编写一个 Python 脚本来计算页面的帖子数,您可以重用相同的脚本来计算任意数量页面的帖子数,而且更好的是,与现在相比,Python 几乎可以立即计算帖子数。你可以手动做。

为了利用这种能力,我们需要函数。函数就像一组可以反复执行的指令,就像菜谱一样。

例如,想象一下制作一个苹果派。如果您自己制作一个苹果派,您可能不需要制作苹果派的说明,但如果您必须制作十几个苹果派并且需要其他人的帮助,您可能需要将说明写下来。这样,无论您有多少助手,他们都可以按照说明进行操作,而您不必单独向每个人解释食谱。

函数就像你写下的一组方向。一旦你有了这组指令,你就可以根据需要多次执行该功能,也可以让其他程序按照指示进行操作。

要执行一个函数,你写出函数的名称,然后是左括号和右括号。在括号内,您指定函数应该修改哪个值或变量。放在函数括号内的数据称为参数。例如,我们一直在使用的 print() 命令是一个名为 print 的函数,它在括号之间接受字符串作为参数。

我们将从讨论 Python 的内置函数开始。当我们在计算机上安装 Python 时,许多创建和维护 Python 的人已经开发并融入了 Python 的一组函数。这些是我们可以立即使用的函数,例如 print() 命令。

这些内置函数中的另一个是 len(),它测量值的长度。例如,我们可以使用 len() 来测量字符串的长度,如下所示:

>>> len("apple pie")
9

此代码计算字符串中的字符数,包括空格。 当我们执行函数时,也称为调用函数,它返回整数 9,这意味着字符串中有 9 个字符。

我们也可以测量值列表的长度。 让我们创建一个名为 apples 的列表,并使用 len() 函数计算列表中有多少项:

>>> apples = ["honeycrisp", "royal gala"]
>>> len(apples)
2

在这种情况下,我们的列表中有两个项目都是字符串:“honeycrisp”和“royal gala”。 当我们在苹果上调用 len() 函数时,它返回整数 2。

内置函数涵盖了 Python 中的许多基本任务。 对于更长的内置函数列表,Python 社区在 https://docs.python.org/3/library/functions.html 上整理了一个有用的页面。

创建自己的函数

要创建我们自己的函数(称为声明函数),我们在交互式 shell 中输入以下内容:

>>> def write_sentence(word):
        new_sentence = word + " is my favorite kind of apple."
        print(new_sentence)

为了定义我们的函数,我们使用关键字 def,它向 Python 发出信号,我们将要编写一个函数。然后我们为函数定义一个名称——在本例中为 write_sentence——并在其后直接添加括号。如果我们希望函数修改一个参数,我们在括号内输入一个参数名称。我们将使用参数名称来引用我们要在函数中修改的对象。

冒号 (:) 表示以下缩进行中的所有内容都是函数的一部分。在像 HTML 这样的 Web 语言中,缩进是可选的,但在 Python 中,缩进是有意义的并且是必需的。缩进,我们通过在行首使用 tab 键或四个空格来实现,它告诉 Python 代码的哪些部分组合在一起。

Python 会将所有缩进的内容与函数指令相关联,直到遇到一行未缩进的代码。一旦 Python 遇到未缩进的行,它就会知道它已到达函数的末尾并移至代码的下一部分。

在缩进的代码中,我们定义了一个名为 new_sentence 的变量,然后使用加号将一个新字符串和字符串“是我最喜欢的苹果”放在一起。我们将这个表达式的结果存储在变量 new_sentence 中,然后打印 new_sentence。

定义函数与调用函数不同。记住一个函数就像一个食谱,所以定义一个函数就像写下这个食谱。但是,如果不使用实际成分执行您的食谱步骤,我们将无法享用美食!因此,最后但并非最不重要的一点是,我们需要通过向它传递一个参数来调用我们的新函数以进行修改。

让我们将“honeycrisp”字符串作为参数传递给我们的 write_sentence() 函数:

>>> write_sentence("honeycrisp")
honeycrisp is my favorite kind of apple.

函数的强大之处在于我们不仅可以为一个字符串执行函数,还可以为任何其他字符串执行函数。接下来我们运行该函数两次,每次使用不同的字符串作为我们函数的参数:

>>> writesentence("royal gala")
royal gala is my favorite kind of apple.
>>> writesentence("granny smith")
granny smith is my favorite kind of apple.

正如这个例子所示,我们可以使用我们的函数和不同的字符串一遍又一遍地造一个新句子。

我们现在已经发现了函数的威力——一组可以多次重复使用的指令。然而,即使您现在可以创建一个函数来按需执行,在您想要使用它的每个实例中调用该函数仍然是一件苦差事,尤其是当您需要使用它数百或数千次时。接下来,您将了解另一个允许您多次自动运行代码的概念:循环。

使用循环

循环允许我们多次执行操作。出于我们的目的,我们将使用循环来遍历列表并为每个项目执行一个操作。为此,我们将使用 for 循环。

为了说明循环的威力,让我们重新审视我们的苹果派食谱。想象一下,我们有四个苹果,我们需要将每个苹果削皮。如果我们有一个机器人可以帮助我们做家务(未来就在眼前!),我们可以编写一个 for 循环,指示机器人穿过我们的一桶苹果并剥每个苹果的皮。我们可能会给我们的机器人助手这样的指令:对于我们苹果桶中的每个苹果,削苹果!

在实际的机器人语言(Python)中,我们必须遵循一个公式来创建一个 for 循环。构造看起来更像这样:

for apple in list_of_apples:
    # This is where we would specify what our robot would do

让我们通过一个有效的 Python 示例来看看这个公式是如何工作的。首先,我们需要定义要循环或迭代的列表。然后,我们需要通过告诉 Python 要循环的列表来声明 for 循环:

>>> apples = ["honeycrisp", "royal gala"]
>>> for apple in apples:
        new_string = "I'm peeling the " + apple
        print(new_string)
I'm peeling the honeycrisp
I'm peeling the royal gala

正如我们之前所做的那样,我们首先定义我们的苹果列表——在本例中,是两个字符串。然后是我们的 for 循环。要遍历列表中的每个项目,我们需要将项目临时存储在一个变量中。为此,我们将苹果列表中的每一项存储在变量 apple 中,一次一个。我们很快就会看到这是如何运作的。

与函数类似,for 循环通常后跟一组指令。它将为我们列表中的每个项目执行这些指令。与函数一样,for 循环也使用冒号告诉 Python 指令何时开始,并使用缩进告诉 Python 哪个代码属于循环。

在循环中,我们将变量 apple 连接到另一个字符串,并将结果字符串存储在名为 new_string 的变量中。然后,我们指示我们的代码打印我们刚刚创建的新字符串。

for 循环一次对列表中的每一项执行相同的指令,因此交互式 shell 会打印出两个新字符串。首先,for 循环将 apple 变量分配给 apples 列表中的第一项,因此 apple 是字符串“honeycrisp”。然后,for 循环执行其中的代码,打印第一个字符串,“我正在剥蜜脆”。这是 for 循环的一次迭代。当 for 循环完成第一次迭代后,它会检查 apples 列表中是否还有更多项,如果有,则将 apple 分配给下一项。在这种情况下,就是字符串“royal gala”。然后,for 循环再次运行其中的代码,打印出“我正在剥皇家晚会”。这是循环的第二次迭代。 for 循环将继续向下遍历项目列表并为每个项目运行代码,直到它用完为止。由于 apples 只包含两个项目,for 循环在两次迭代后完成循环。

在网络上收集数据时,我们会经常看到循环。当我们以编程方式在线收集数据点时,我们会将标题或时间戳等数据放入一个列表中,并通过使用列表迭代它们来对每个数据点运行函数。例如,任何给定推文的时间戳可能存储为像 2019-01-22 06:58:44 这样的长字符串,因此我们可能需要编写一个函数来将日期与发布时间分开。使用循环允许我们在每个日期操作该函数,而不必为每个时间戳手动完成工作。

使用条件

最后但并非最不重要的,让我们谈谈逻辑。循环可以帮助我们自动处理大量数据并对每一项执行操作,但每一项都被同等对待。当我们遇到不应被同等对待的项目时,我们的脚本应该怎么做?这就是条件的用武之地。

条件告诉 Python 根据是否满足条件来运行代码。最常用的条件之一是 if 子句,它告诉 Python 如果条件为真,它应该做一件事。如果不满足此条件,则 else 子句会告诉 Python 运行其他一些代码。虽然 if 子句可以单独使用,但 else 子句必须始终与 if 子句配对使用。

我们通常使用带有逻辑运算符的条件 - 允许我们确定条件是真还是假的符号。例如,在数学课上,您可能已经使用了大于号 (>) 来进行陈述。例如,语句 5 > 9 表示“五大于九”。由于五实际上并不大于九,因此该陈述是错误的。 Python 中的逻辑运算符以类似的方式工作,只是某些运算符的符号不同。例如,当你在数学中测试相等时,你使用一个等号 (=),但是因为 Python 使用单个等号进行赋值语句,所以 Python 中检查两个值是否相等的运算符是两个等号 (= =)。

表 1-1 包含可用于条件语句的运算符列表。

表 1-1:逻辑运算符

Operator What it does Example
`= 如果运算符左侧和右侧的值相等,则条件为真。 (“pie” == “cake”) is not true.
!= 如果运算符左侧和右侧的值不相等,则条件为真。 (“pie” != “cake”) is true.
> 如果运算符左边的值大于右边的值,则条件为真。 (4 > 10) is not true.
< 如果运算符左边的值小于右边的值,则条件为真。 (4 < 10) is true.
>= 如果运算符左边的值大于或等于右边的值,则条件为真。 (4 >= 10) is not true.
<= 如果运算符左边的值小于或等于右边的值,则条件为真。 (4 <= 10) is true.

现在您已经了解了 if 子句和条件语句如何工作的基础知识,让我们看一个例子。如果食物变量包含“pie”,我们将告诉 Python 给我们一些馅饼,或者当食物不等于“pie”时打印其他内容。首先,将字符串“pie”分配给变量 food。然后输入 if 运算符,后跟一个条件。在这种情况下,条件是 food == “pie”,这意味着条件是变量 food 具有值“pie”,后跟一个冒号 :。 if 子句使用缩进来表示范围,就像函数和循环一样。使用 tab 键缩进 if 子句后面的行。如果满足条件 food == “pie”,冒号后面的任何缩进代码现在都被视为 Python 将执行的一部分。在这种情况下,如果 food == “pie”,那么 Python 将打印字符串“Give me some pie!”。然后,使用操作符 else 和一个冒号,我们告诉 Python 如果不满足条件 food == “pie” 应该怎么做。同样,使用 Tab 键写出这些指令,这样 Python 就知道缩进的代码包含在不满足初始条件时应该执行的指令。在这种情况下,我们希望 Python 打印字符串“我不饿”。

>>> food = "pie"
>>> if food == "pie" :
        print("Give me some pie!")
    else:
        print("I'm not hungry")
Give me some pie!

当我们在交互式 shell 中运行这段代码时,它应该打印字符串“给我一些馅饼!”因为我们的条件(如果食物==“馅饼”)得到满足。

我们将在社交媒体上收集的数据可能是不规则的,如果我们的代码不是用来处理特性的,这可能会导致错误。 if 子句是我们将“最坏情况”构建到我们的数据收集脚本中以处理这些情况的好方法。假设我们想使用 Python 来收集 100 个不同 Facebook 群组列表的描述。由于管理员不必为他们的组编写描述,因此某些组可能有描述,而其他组可能没有。如果您使用 for 循环遍历整个组列表,Python 将查找每个组的描述,即使是那些可能没有的组。这可能会混淆 Python 脚本。在这些情况下,编写使用条件来指示 Python 会很有用:如果该组有描述,Python 应该收集该信息,否则它应该记录一个通用字符串,例如“这个组没有描述”来代替说明。

概括

这本书涵盖了很多方面。虽然您无法成为每种 Web 语言(前端或后端)的专家,但希望本章能帮助您了解 Web 语言的基本功能。在很多方面,学习编程语言类似于学习口语:首先我们必须学习一些最常见的单词和语法,然后我们才能扩大词汇量并变得更加流利。将您刚刚学到的函数名称和 HTML 标记视为编码语言的词汇,将条件、循环和 if 子句等概念视为语法。这些基础知识将帮助您阅读我们在接下来的章节中编写的脚本,并且随着我们逐个示例的进行,您将能够在此基础上进行构建,成为更流畅的编码员。

在下一章中,我们将探索作为数据源的应用程序编程接口 (API),您将使用新学到的 Python 知识从 YouTube API 请求和访问数据。