>>> from env_helper import info; info()
页面更新时间: 2023-08-21 18:58:34
运行环境:
    Linux发行版本: Debian GNU/Linux 12 (bookworm)
    操作系统内核: Linux-6.1.0-11-amd64-x86_64-with-glibc2.36
    Python版本: 3.11.2

4.1. 从Web抓取信息

少数可怕的时候,我没有 Wi-Fi 。这时才意识到,我在计算机上所做的事,有多少实际上是在因特网上做的事。完全出 于习惯,我会发现自己尝试收邮件、阅读朋友的推特,或回答 问题:“在 Kurtwood Smith 演出1987年的机械战警之前, 曾经演过主角吗?”

因为计算机上如此多的工作都与因特网有关,所以如果程序 能上网就太好了。“Web抓取”是一个术语,即利用程序下载并 处理来自 Web的内容。例如,Google运行了许多web抓取程序, 对网页进行索引,实现它的搜索引擎。在本章中,你将学习 几个模块,让在Python中抓取网页变得很容易。

webbrowser:是Python自带的,打开浏览器获取指定页面。

requests :从因特网上下载文件和网页。

Beautiful Soup:解析HTML,即网页编写的格式。

selenium:启动并控制一个Web浏览器。 selenium 能够填写表单, 并模拟鼠标在这个浏览器中点击。

4.1.1. 项目:利用 webbrowser 模块的 maplt.py

webbrowser 模块的 open() 函数可以启动一个新浏览器, 打开指定的URL 。在交互式环境中输入以下代码:

>>> import webbrowser
>>> webbrowser.open('http://inventwithpython.com/')
False

Web 浏览器的选项卡将打开 URL http://inventwithpython.com/。 这大概就是 webbrowser 模块能做的唯一的事情。 既使如此, open()函数确实让一些有趣的事情成 为可能。例如,将一条街道的地址拷贝到剪贴板, 并在Google地图上打开它的地图,这是很繁琐的事。 你可以让这个任务减少几步,写一个简单的脚本, 利用剪贴板中的内容在浏览器中自动加载地图。 这样,你只要将地址拷贝到剪贴板,运行该脚本, 地图就会加载。你的程序需要做到:

  • 从命令行参数或剪贴板中取得街道地址。

  • 打开Web浏览器,指向该地址的Google地图页面。

这意味着代码需要做下列事情:

  • 从 sys.argv 读取命令行参数。

  • 读取剪贴板内容。

  • 调用 webbrowser.open() 函数打开外部浏览器。

打开一个新的文件编辑器窗口,将它保存为 maplt.py 。

第1步:弄清楚 URL

根据附录B中的指导,建立 maplt.py , 这样当你从命令行运行它时,例如

C:\> mapit 870 Valencia St, San Francisco, CA 94110

该脚本将使用命令行参数,而不是剪贴板。 如果没有命令行参数, 程序就知道要使用剪贴板的内容。

首先你需要弄清楚,对于指定的街道地址, 要使用怎样的 URL 。你在浏览器中打开 http://maps.google.com/ 并查找一个地址时,地址栏中的URL看起来就像这样: https:// www.google.com/maps/place/870+Valencia+St/@37.7590311,-122.4215096, 17z/data= !3m1!4b1!4m2!3m1!1s0x808f7e3dadc07a37:0xc86b0b2bb93b73d8.

地址就在URL中,但其中还有许多附加的文本。 网站常常在URL中添加额外的数据,帮助追踪访问 者或定制网站。但如果你尝试使用 https://www.google. com/maps/place/870+Valencia+St+San+Francisco+CA/, 会发现仍然可以到达正确的页面。所以你的程序可以设置 为打开一个浏览器,访问https://www.google.com/maps/place/your_address_string (其中 your_address_string 是想查看地图的地址)。

第2步:处理命令行参数

让你的代码看起来像这样:

>>> #! python3
>>>
>>> # maplt.py - Launches a map in the browser using an address from the
>>>
>>> # command line or clipboard.
>>>
>>> import webbrowser, sys
>>> if len(sys.argv) > 1:
>>>     # Get address from command line.
>>>     address = ' '.join(sys.argv[1:])
>>>
>>> # TODO: Get address from clipboard.

在程序的#!行之后,需要导入 webbrowser 模块, 用于加载浏览器;导入 sys 模块,用于读入可能 的命令行参数。 sys.argv 变量保存了程序的文件 名和命令行参数的列表。如果这个列表中不只有文件名, 那么 len(sys.argv) 的返回值就会大于1,这意味 着确实提供了命令行参数。

命令行参数通常用空格分隔,但在这个例子中,你希望 将所有参数解释为一个字符串。因为 sys.argv 是 字符串的列表,所以你可以将它传递给 join()方法, 这将返回一个字符串。你不希望程序的名称出现在这个 字符串中,所以不是使用 sys.argv ,而是使用 sys.argv[1:] ,砍掉这个数组的第一个元素。 这个表达式求值得到的字符串,保存在 address 变量中。

如果运行程序时在命令行中输入以下内容:

mapit 870 Valencia St, San Francisco, CA 94110

… sys.argv 变量将包含这样的列表值:

>>> ['mapIt.py', '870','Valencia','St, ','San', 'Francisco, ', 'CA', '94110']
['mapIt.py', '870', 'Valencia', 'St, ', 'San', 'Francisco, ', 'CA', '94110']

address 变量将包含字符串 '870 Valencia St, San Francisco, CA 94110' 。

第3步:处理剪贴板内容,加载浏览器

以下运行需要先安装:

sudo apt install python3-pyperclip

让你的代码看起来像这样:

>>> #! python3
>>> # maplt.py - Launches a map in the browser using an address from the
>>> # command line or clipboard.
>>>
>>> import webbrowser, sys, pyperclip
>>> if len(sys.argv) > 1:
>>>     # Get address from command line.
>>>     address = ' '.join(sys.argv[1:])
>>>
>>> else:
>>>     # Get address from clipboard.
>>>     address = pyperclip.paste()
>>>
>>> webbrowser.open('https://www.google.com/maps/place/'+ address)
False

如果没有命令行参数,程序将假定地址保存在剪贴板中。 可以用 pyperclip.paste() 取得剪贴板的内容, 并将它保存在名为 address 的变量中。最后, 启动外部浏览器访问 Google 地图的URL,调用 webbrowser.open() 。

虽然你写的某些程序将完成大型任务,为你节省数小时的时间,但使用一个程序, 在每次执行一个常用任务时节省几秒钟时间,比如取得一个地址的地图,这同样令人满意。 下表比较了有 maplt.py 和没有时,显示地图所需的步骤。

不用和利用 maplt.py 取得地图

手工取得地图

利用 maplt.py

高亮标记地址

高亮标记地址

拷贝地址

拷贝地址

打开Web浏览器

运行 maplt.py

打开 http://maps.google.com/

点击地址文本字段

拷贝地址

按回车

看到程序让这个任务变得不那么繁琐了吗?

第4步:类似程序的想法

只要你有一个URL, webbrowser 模块就让用户 不必打开浏览器,而直接加载一个网站。其他程序 可以利用这项功能完成以下任务:

  • 在独立的浏览器标签中,打开一个页面中的所有链接。

  • 用浏览器打开本地天气的URL。

  • 打开你经常查看的几个社交网站。