10.2 网络数据编程基础
如果我们已经清楚地知道所获取的网络信息的位置,那么我们所面对的问题将是如何将其抓取到本地以便我们后续的分析研究。诚然,我们可以到每个网页上去复制我们所需要的内容,然后再粘贴这些信息(如果网页允许进行复制粘贴操作),但这一过程可能会耗费几个小时或更长时间,更重要的是重复的复制粘贴动作会让人觉得枯燥乏味且可能出错。而通过编写一个小程序就可以将这一重复且冗长的过程交由计算机完成了。
实现这一效果的方法很多,本节我们将简单介绍当下流行的一种计算机语言Python,带领大家一起动手,通过不超过20行的代码实现数据的规模抓取。
这里大家可能会产生疑问,为什么选择使用Python而非其他的工具。因此我们首先简单介绍一下Python的优势:
1.易于使用、功能强大,不仅对专业人士友善,对初学者也同样友善。Python的语言接近于人类语言(英语)。作为一种高级语言,Python阅读起来非常接近英语,这大大地减轻了我们这样的初学者学习语法的压力,从而使我们能够专注于学习编程的逻辑——它允许我们像程序员一样进行逻辑思考,而不是花费大量时间纠缠在令人困惑的语法上。以打印“hello world”为例,如果我们使用的是java,那么需要写下3行命令,而如果使用Python,却只需要1行就足够了(如图10-1)。
图10-1 “hello world”Java 与 Python语法
2.Python的使用存在趣味性。乐趣是人类进行学习的巨大动力,和其他语言不同,Python能使我们快速地实现所设想的效果,进而产生令人满意的体验。事实上,接下来我们对于Python的学习就不同于其他语言的学习——按部就班地介绍各种语法,而是通过几个实际会被使用的项目,帮助大家在快速掌握Python语法的同时,达到我们所需要的对于网络信息的获取。
3.丰富的资源。Python拥有85,000多个用户可以访问使用的Python模块(或者叫库,我们可以简单地把它理解成模板),不同模块为用户提供了在自己电脑上实现各种目的的预打包功能。借此用户可以解决各种各样的问题,比如执行网络数据获取、高级数据分析,以及实现数据可视化呈现等。
4.Python是免费的且在世界范围内是流行的。
希望通过这样的介绍,能够打消一些大家对于计算机语言学习的顾虑。接下来我们将以网页信息抓取为目标,一步步帮助大家通过使用Python快速掌握对网站数据的获取。
10.2.1 Python安装中的问题
如果你想在自己的电脑上开始Python编程,你需要下载并安装Python。由于Python是开源的,所以大家可以轻松地在其官网上通过下载获得(网址:www.python.org)。具体的安装根据软件安装过程中的提示进行即可。这里仅就第一次使用时可能会发生的问题做简要解释。
首先,在进入官网下载页面后,我们会发现Python同时提供了Python2 和Python3的版本更新,请注意这两者间存在语法的区别,我们后续的介绍将基于Python3进行。所以请根据自己的电脑系统(Windows、Mac OS、Linux等)选择合适的Python3版本进行下载安装。
当Python被安装到电脑后,要想打开Python,我们需要找到并点击 IDLE程序。这里以Python 3.4为例进行简单介绍。(目前Python官方最新版本为Python3.8,请下载安装最新版)
1.可以通过点击系统-Python3.4找到IDLE的位置:
2.通过IDLE我们可以进入到Python的结果窗口,它是用来展示程序结果的地方。当程序被正常打开时,你会看到一个这样的窗口:
如果你使用的是Mac OS,那么系统自带了Python 2.7,请注意我们已经说过了,Python2和Python3的语法是存在差异的,所以你依旧需要先去官网上下载Python3的最新版进行安装,并通过IDLE进入。
10.2.2 Python的基础语法
现在我们开始写一个关于温度转换的小程序,这是Python入门中一个既简单又有着丰富语法知识的实例。但有些必备的知识需要先掌握,所以我们先简单介绍一下Python编程的基础知识。当我们可以顺利启动软件时,我们进入了刚刚看到过的窗口(图10-2),它被称为结果运行窗口,是Python立即执行所给予的任何命令的窗口。
图10-2 结果运行窗口
我们可以在这个窗口中做一些基础的语句编写,比如让Python打印数字和字符串。当我们根据光标提示输入print(5)并回车时,Python会帮我们将数字5打印出来。同样,当我们再次输入print(“你好 Python”)并回车时,Python会将字符串“你好 Python”打印出来(图10-3)。虽然很简单,但这却是你写出的第一个可以被计算机执行的程序。请注意在Python语句的编写中,除了输入汉字外,其他所有字符都应该在英文输入状态下完成(即半角输入),且字符串一定在引号里(包括单引号和双引号)。
图10-3 语句缩写
相较于这样的针对每个语句逐行运行,在实际操作中我们更希望通过一个程序文件将多个语句一次执行并只得到最终结果,这就需要一个专门用来写语句的地方。我们可以通过点击视窗右上角的File(文件),选择 New File (新文件),创建一个新文件(图10-4)。
图10-4 创建新文件
现在我们就可以把任何字符的命令输入新生成的窗口中,它被称为编译窗口,比如:
print(5)
print(‘Hello World 你好世界’)
并通过Run选择Run Module来执行这个程序,快捷键为F5(图10-5)。根据提示保存文件(.py格式)后,在弹出的结果窗口中得到运行的最终结果(图10-6)。
图10-5 编译窗口
图10-6 运行结果
在Python中+号是一个很有用的符号,通过使用+号,我们能够得到一些复杂的东西。但需要注意的是,如果+号的两边是数字,则+号表示求和,而当+号的两边都是字符串(再次强调凡是字符串一定有引号),+号表示连接,即+号使得多个字符串依次被打印。
请大家尝试在编译窗口输入以下内容,并在结果窗口查看结果:
print(5+3)
print(‘你好 ’+‘Python’)
Python中有的地方空格很重要,有的地方却根本无所谓。在上面的第一行语句里+号左右的空格并没有任何实质作用,只是有助于代码编写时的美观,可以被删掉,并不会影响到结果。但如果把空格放在一个字符串里(第二行语句),Python 将会打印这个空格,因为此时的空格被Python理解成了字符串中的一个字符了。我们随后还会看到,空格在Python中另一个很重要的作用。在这里请大家务必开始重视Python中的空格。
除了+号,Python中另一个重要的符号和我们日常的理解也不相同,那就是等号。在Python中=表示赋值,被称为赋值符,而等于则通过两个等号(==)来表示。我们可以将任意的值通过赋值符赋给一个变量名称。一个变量名称就像是一个邮箱的地址,它可以自行拟定名称(但有一些限制,相关内容请查看本章延伸与讨论部分),但无法直接告诉你里面的东西(值)是什么,它能告诉你的是去哪儿能找到你想要的值。例如:
x=5将整数5赋给了变量x,这个过程即赋值(Assignment);
这时我们用x*4将会得到20,这个得到20的过程被称为调用(Call)。
当我们看到x*4时无法知道x到底代表了多少,但我们知道了要往上去找到的东西是什么——x被我们赋予了什么。
请在编译窗口输入以下语句并查看结果:
y=3
print(y+5)
如果在上面练习的基础上,你尝试把一个数字和一个字符串用+号加起来,系统会报错,这是为什么呢?在Python中无论数字、字符或是我们暂时还没有介绍到的值,它们都是有类型的。比如5的类型就是整数,在Python中被称为整型(integer),用int表示;‘你好’的类型是字符串,用str表示。字符串(string)是字符的序列,在Python中通过引号表示出来,可以是单引号也可以是双引号,但必须成对出现。要解决前面的问题,你可以使用 int()函数把一个字符串类型改为数字,或者使用str()函数把数字类型改为字符串。请尝试输入以下内容,想一想a的类型最终会是什么?
a=5
a=a+1
print(a)
a=a*2
print(a)
如果这时还存在一个变量b:
b=‘Python’
我们希望得到的结果是一个字符串“5Python”要怎么做呢?我们需要将变量a的属性变为字符串,然后通过+号(连接符)将两个字符串连接起来,如图10-7所示:
图10-7 字符串运算
另外,Python对于大小写是非常敏感的。print()和Print()或者 prInt(),‘Joe’或‘joe’在Python看来都是不一样的。
通过上面的简单介绍,我们了解了如何进行赋值以及值的属性等内容。除此之外,我们发现如果想实现某个特定的功能,需要使用到一些特定的单词,比如打印print(),转化为字符串str(),转化为整型int(),这些在Python中被称为函数。通过对函数的调用可以实现特定的功能,其语法结构为:函数名+小括号,括号中可以写入参数。Python的函数很多,甚至用户可以自己创建函数,随着内容的深入,大家会逐渐接触到。在这里我们再多介绍一个非常有用的函数——input(),即输入函数,通过这个函数可以实现让电脑向我们索取信息(输入完毕然后按Enter键)并把输入的信息存入一个变量中。注意,通过input()函数向电脑输入的信息,Python会默认其为字符串类型。所以当你输入整数20时,Python会认为它是‘20’。input函数的括号内可以写入提示性语句,以帮助用户在面对电脑索取时明白需要输入的信息是什么。图10-8是一个关于input()使用的实例。
图10-8 input()的使用
本节的最后我们来介绍Python中一个十分重要的语句:条件语句(conditional statements,if语句)。在一个实用的程序中,几乎总是需要根据条件,改变程序相应的行为。条件语句赋予我们这种能力,它告诉Python只在特定情况下来做某些事情。由于Python语言非常接近于英语,所以条件语句的语法对我们几乎不造成困扰。让我们先看一个有关年龄的例子:
Userage=input(‘您的年龄是?’)#请求用户输入年龄
age=int(Userage)#将用户输入的年龄(字符串属性)转化为整型(整数)
if age<=100:#开始进行条件判断
print(‘你真有活力!’)
else:
print(‘您老当益壮!’)
很显然,Python执行条件分支语句的逻辑很清楚,即当if后的表达式成立时,执行if所对应的语句。当if后的表达式不成立时,则执行else所对应的语句。那么如何判断if和else分别对应了哪些语句呢?观察上面的语句会发现,Python是通过空格的不同进行判断的,这被我们称为缩进(indent)。若逻辑条件为真,那么if所对应的缩进语句得以执行,若逻辑条件为假,那么缩进的语句就会被跳过。我们可以根据实际需要编写多个条件分支,例如:
Userage=input(‘您的年龄是?’)
age=int(Userage)
if age<=30:
print(‘你真年轻!’)
if 30<age<=60:
print(‘你是支柱!’)
if 60<age<=100:
print(‘您真老当益壮。’)
除上面的写法外,还可以通过使用elif来简化程序运行的逻辑。假设用户输入的年龄为20,那么计算机在执行到第三行语句时会判断if条件成立并执行相应的语句体。我们知道此刻程序可以停止了,但当我们所有的分支都是用if来写时,计算机的逻辑会认为这些条件都是并列的,因而即使第一个if语句被判断成立并执行后,计算机仍会继续带着20进入下一个if语句的判断,直到最后一个if条件判断完成的位置。这一过程实际上大大增加了计算机的开销。如果你的现实需求是满足前一个条件后,其后多个条件被排除,那么elif就是解决的方法。当其中一个条件分支被判断成立后,在它后面的所有的条件分支都将不再被执行(即跳过)。elif是if与else的缩写,其语法规则与if相同:
Userage=input(‘您的年龄是?’)
age=int(Userage)
if age<=30:
print(‘你真年轻!’)
elif 30<age<=60:
print(‘你是支柱!’)
elif 60<age <=100:
print(‘您真老当益壮。’)
else:
print(‘人瑞。’)
甚至,我们可以在if条件中再次写入条件分支,这种结构被称为嵌套结构,在这里不再做解释。总的来看,条件分支的语法为:
if 条件 :
条件成立时所执行的语句体
请注意缩进是Python的灵魂,它实现了Python语言的精简,因而缩进是不可以错的。此外,在编写if语句时,不要忘记了冒号,并记得语句体要通过缩进体现出来。在Python中一层缩进往往使用四个空格(或一个Tab键)来实现。
在上述的语句中还出现了一类符号,叫比较运算符,表10-1所列为Python所使用到的比较运算符。
表10-1 比较运算符
续表