注:文章原文为Dr. Charles Severance 的 《Python for Informatics》。文中代码用3.4版改写,并在本机测试通过。
12.5 HTML分析和网页抓取
urllib库一项最常用的功能是抓取网页。就是我们编写一个程序,将自己伪装成网页浏览器,在获取网页之后,再以查找模式检索网页中的数据。
以搜索引擎Google为例,它将查看一个网页的源码,然后抽取其中的链接,再用这些链接获取网页、抽取链接,并一直循环。使用这个技巧,Google几乎爬遍网页上的所有页面。
Google同时利用链接在网页中出现的频次,评估一个网页的的重要性,以及排列在搜索结果中的先后。
12.6 用正则表达式分析HTML
用正则表达式重复查找和抽取匹配特定模式的内容来分析HTML是一个简单的方法。下面是一个简单的网页:
<h1>The First Page</h1>
<p>
If you like, you can switch to the
<a href="http://www.dr-chuck.com/page2.htm">
Second Page</a>.
</p>
我们可以创建一个格式良好的正则表达式来匹配和抽取上面文本中的链接内容,具体如下:
href="http://.+?"
我们的正则表达式查找以“href="http://"开始的,后面跟着一个或更多的字符".+?",最后是另一个双引号。在加号后面的问号表示这个表达式的匹配是”非贪婪“模式。”非贪婪“模式是最小匹配模式,而”贪婪“模式试图找到最大可能的匹配字符串。
我们还需在正则表达式中添加括号,从而抽取我们想要的匹配字符串,并编写以下程序:
import urllib.request
import re url = input('Enter - ')
html = urllib.request.urlopen(url).read().decode('utf-8')
links = re.findall('href="(http://.+?)"', html)
for link in links:
print(link)
正则表达式的findall()方法将为我们抽取一个匹配的字符串列表,即在两个双引号直接的链接文本。
当我们运用这个程序,我们将得到以下输出:
python urlregex.py
Enter - http://www.dr-chuck.com/page1.htm
http://www.dr-chuck.com/page2.htm
python urlregex.py
Enter - http://www.py4inf.com/book.htm
http://www.greenteapress.com/thinkpython/thinkpython.html
http://allendowney.com/
http://www.py4inf.com/code
http://www.lib.umich.edu/espresso-book-machine
http://www.py4inf.com/py4inf-slides.zip
当你的HTML格式良好并可预见的,那么正则表达式将工作得非常好,但是因为那里还有很多不完整的HTML,你会发现只用正则表达式可能会漏掉一些有效的链接或者被坏的数据结束掉。这样的问题可以用一个强健的HTML分析库BeautifulSoup解决。下一节我们将讲如何用BeatuifulSoup分析HTML。
(译者注:在上面这个程序中你收入http://www.sina.com.cn,你会发现程序因解码异常终止,将程序稍作修改解决异常终止,但仍然抓取不到链接信息)。
import urllib.request
import re url = input('Enter - ')
html = urllib.request.urlopen(url).read()
links = re.findall(b'href="(http://.*?)"', html)
for link in links:
print(link.decode('utf-8'))