>>> 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。

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