没有 Wi-Fi 才是最可怕的事情,也许这时才意识到,在计算机上所做的事, 有多少实际上是在因特网上做的事。 因为计算机上如此多的工作都与因特网有关,所以如果程序 能上网就太好了。“Web抓取”是一个术语,即利用程序下载并 处理来自 Web的内容。例如,Google运行了许多web抓取程序, 对网页进行索引,实现它的搜索引擎。在本章将学习 几个模块,让在Python中抓取网页变得很容易。
webbrowser
: 是Python自带的,打开浏览器获取指定页面。requests
: 从因特网上下载文件和网页。Beautiful Soup
: 解析HTML,即网页编写的格式。selenium
: 启动并控制一个Web浏览器。selenium
能够填写表单, 并模拟鼠标在这个浏览器中点击。
import webbrowser
webbrowser.open('http://inventwithpython.com/')
False
Web 浏览器的选项卡将打开 URL
http://inventwithpython.com/。
这大概就是 webbrowser
模块能做的唯一的事情。
既使如此, open()
函数确实让一些有趣的事情成
为可能。例如,将一条街道的地址拷贝到剪贴板,
并在Google地图上打开它的地图,这是很繁琐的事。
可以让这个任务减少几步,写一个简单的脚本,
利用剪贴板中的内容在浏览器中自动加载地图。
这样只要将地址拷贝到剪贴板,运行该脚本,
地图就会加载。程序需要做到:
从命令行参数或剪贴板中取得街道地址。
打开Web浏览器,指向该地址的Google地图页面。
这意味着代码需要做下列事情:
从
sys.argv
读取命令行参数。读取剪贴板内容。
调用
webbrowser.open()
函数打开外部浏览器。
打开一个新的文件编辑器窗口,将它保存为 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
是想查看地图的地址)。
maplt.py
- 通过命令行参数或剪贴板地址在浏览器中打开地图。
#! python3
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']
sudo apt install python3-pyperclip
让代码看起来像这样:
maplt.py
- 通过命令行参数或剪贴板地址在浏览器中打开地图。
#! python3
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)
--------------------------------------------------------------------------- ModuleNotFoundError Traceback (most recent call last) Cell In[4], line 1 ----> 1 import webbrowser, sys, pyperclip 2 if len(sys.argv) > 1: 3 # Get address from command line. 4 address = ' '.join(sys.argv[1:]) ModuleNotFoundError: No module named 'pyperclip'
如果没有命令行参数,程序将假定地址保存在剪贴板中。
可以用 pyperclip.paste()
取得剪贴板的内容,
并将它保存在名为 address
的变量中。最后,
启动外部浏览器访问 Google 地图的URL,调用 webbrowser.open()
。
虽然写的某些程序将完成大型任务,节省数小时的时间,但使用一个程序,
在每次执行一个常用任务时节省几秒钟时间,比如取得一个地址的地图,这同样令人满意。
下表比较了有 maplt.py
和没有时,显示地图所需的步骤。看到程序让这个任务变得不那么繁琐了吗?
手工取得地图 | 利用 maplt.py |
---|---|
高亮标记地址 | 高亮标记地址 |
拷贝地址 | 拷贝地址 |
打开Web浏览器 | 运行 maplt.py |
打开 http://maps.google.com/ | |
点击地址文本字段 | |
拷贝地址 | |
按回车 |