
1.3 大程序
现在来点儿完全不一样的东西:例1-4展示的Python程序会执行一系列更复杂的任务。别指望现在就能看明白这段程序,否则我撰写本书干吗?!这个例子的目的是让你感受一下一般的Python程序是什么样子。如果你了解其他计算机语言,那么不妨和Python做一下对比。即使还不懂Python,也试试能否在阅读程序后面的讲解之前猜出每一行代码都是干什么的。你已经见过Python列表和字典的例子,这个程序带来了另外一些特性。
例1-4 archive.py
1 import webbrowser 2 import json 3 from urllib.request import urlopen 4 5 print("Let's find an old website.") 6 site = input("Type a website URL: ") 7 era = input("Type a year, month, and day, like 20150613: ") 8 url = "http://archive.org/wayback/available?url=%s×tamp=%s" % (site, era) 9 response = urlopen(url) 10 contents = response.read() 11 text = contents.decode("utf-8") 12 data = json.loads(text) 13 try: 14 old_site = data["archived_snapshots"]["closest"]["url"] 15 print("Found this copy: ", old_site) 16 print("It should appear in your browser now.") 17 webbrowser.open(old_site) 18 except: 19 print("Sorry, no luck finding", site)
本书第1版中给出的样例程序会连接YouTube网站,获取当前评价最高的视频信息,比如“Charlie Bit My Finger”。第2版刚完稿没多久,谷歌便停止了这项服务,样例程序也就没法工作了。新的样例程序1-4选择了另一个网站,即位于Internet Archive(互联网档案馆)中的Wayback Machine(时光机),这是一项免费服务,保存了20年多间数十亿个Web页面以及电影、电视节目、音乐、游戏和其他数字产品。第18章会展示更多Web API相关的例子。
该程序会要求你输入一个URL和日期,然后查询Wayback Machine是否保存了该站点当时的副本。如果能找到一个副本,就将信息返回给Python程序,由后者打印出URL并在Web浏览器中显示。重点在于展示Python如何处理各种任务,即获取你的输入,与互联网上的站点通信,获取页面内容,从中提取URL,以及让Web浏览器显示对应的页面。
如果得到的是一个HTML格式的正常Web页面,则需要想办法将其显示出来,这可不是一件轻松活儿,我们乐于让Web浏览器代劳。另外还要尝试提取所需的部分内容(详见第18章的Web爬取)。不管做出哪种选择,都意味着更多的工作和更大的程序。相反,Wayback Machine以JSON格式返回数据。JSON(JavaScript object notation,JavaScript对象记法)是一种人类可读的文本格式,描述了其中数据的类型、值以及顺序。它是另一种小语言,已经成为不同计算机语言和系统之间交换数据的流行方式。第12章会介绍更多关于JSON的内容。
Python程序可以将JSON文本转换成Python 数据结构,在接下来的几章中你会看到,这种数据结构和你自己创建出来的一样。我们只选择一小部分(旧网页在Internet Archive网站中的URL)。同样,这是一个完整的Python程序,你可以自己运行。为了让这个例子简短一些,我们在程序中仅加入了很少的错误检查。行号不是程序的一部分,显示它们只是为了帮助你阅读程序后面给出的描述。
这个Python程序只有短短数行,但是干的活儿可不少。你现在可能还不知道下面这些术语是什么意思,不过在随后几章中就会明白了。每一行代码的功能如下。
01.从Python 标准库中导入模块webbrowser(使其可供该程序使用)。
02.从Python标准库中导入模块json。
03.从Python标准库中导入模块urllib.request的urlopen 函数。
04.空行,以免代码看起来太拥挤。
05.打印出一些初始文本。
06.打印问题,询问URL,读取用户输入,将其保存在变量site中。
07.打印另一个问题,这次要读取年、月和日,然后将其保存在变量era中。
08.构建字符串变量url,让Wayback Machine查找指定站点当时的副本。
09.连接到URL的Web服务器,请求特定的Web服务。
10.获取响应数据并将其赋给变量contents。
11.将contents 解码为JSON格式的字符串并赋给变量text。
12.将text转换到data——Python数据结构。
13.错误检查:尝试运行接下来的4行代码,如果出现任何错误,就执行程序最后一行(位于except之后)。
14.如果能找到站点当时的副本,就从3级Python 字典中提取URL。注意,该行和接下来的两行是缩进的。Python由此知道这几行代码属于try。
15.打印提取出的URL。
16.打印后几行代码执行后会出现什么结果。
17.在Web浏览器中显示找到的页面。
18.如果前4行出现任何错误,那么Python就直接跳转到这里。
19.如果出现错误,就打印消息以及查找的站点。该行采用缩进形式,因为只有前一行的except执行之后才能执行这一行。
在终端窗口中运行这个程序,输入网站URL和日期,得到下列文本输出:
$ python archive.py Let's find an old website. Type a website URL: exampleurl Type a year, month, and day, like 20150613: 20151022 Found this copy: http://web.archive.org/web/20151102055938/exampleurl It should appear in your browser now.
图1-3会出现在浏览器中。

图1-3:来自Wayback Machine
例1-4用到了一些Python 标准库模块(Python自带的程序),不过这并没有什么神奇的。Python还拥有大量优秀的第三方软件。例1-5使用外部Python软件包requests进行了重写。
例1-5 archive2.py
1 import webbrowser 2 import requests 3 4 print("Let's find an old website.") 5 site = input("Type a website URL: ") 6 era = input("Type a year, month, and day, like 20150613: ") 7 url = "http://archive.org/wayback/available?url=%s×tamp=%s" % (site, era) 8 response = requests.get(url) 9 data = response.json() 10 try: 11 old_site = data["archived_snapshots"]["closest"]["url"] 12 print("Found this copy: ", old_site) 13 print("It should appear in your browser now.") 14 webbrowser.open(old_site) 15 except: 16 print("Sorry, no luck finding", site)
新版本更短小,对大多数人而言,可读性应该更好。有关requests的更多细节,参见第18章,外部编写的Python软件参见第11章。