Python:将包含大量图形的页面保存为.html文件
我想把一个访问过的网页保存到电脑上,保存成一个文件。我使用了urllib和URLOpener这两个工具。我选择了一个网站http://emma-watson.net/。文件保存成.html格式是没问题的,但当我打开这个文件时,我发现顶部的主图像(上面有链接到其他子页面的书签)没有显示,还有一些其他元素(比如POTD)也没显示。请问我该怎么做才能正确保存这个网页,让它在电脑上完整显示呢?
def saveUrl(url):
testfile = urllib.URLopener()
testfile.retrieve(url,"file.html")
...
saveUrl("http://emma-watson.net")
真实网页的截图:
我电脑上打开的文件截图:
1 个回答
你想做的是创建一个非常简单的网页抓取工具,也就是说,你想找到文件中的所有链接并下载它们,但不想进行递归抓取,也不需要复杂的过滤或后处理等。
你可以使用一个完整的网页抓取库,比如scrapy
,只需将其限制为深度为1,并且不启用其他功能。
或者,你也可以手动来做。选择你喜欢的HTML解析器(BeautifulSoup
使用起来很简单;html.parser
是标准库自带的;还有很多其他选择)。下载页面,然后解析下载下来的文件,扫描其中的img
、a
、script
等标签,找出带有网址的链接,然后下载这些网址,这样就完成了。
如果你想把所有内容存储在一个文件中,有很多种“网页归档文件”格式可以选择,不同的浏览器(和其他工具)支持不同的格式。大多数格式的基本思路是,你创建一个特定布局的压缩文件,扩展名用.webarch而不是.zip。这个部分比较简单。但你还需要把所有的绝对链接改成相对链接,这就稍微复杂一点。不过,使用像BeautifulSoup
、html.parser
或lxml
这样的工具,这也不是特别难。
顺便提一下,如果你并不真的需要使用UrlOpener
,那你就是在给自己增加不必要的麻烦;直接使用urlopen
就可以了。而且,正如文档所提到的,你应该使用urllib2
,而不是urllib
;实际上,urllib.urlopen
在2.6版本后就不再推荐使用了。而且,即使你确实需要使用一个明确的打开器,正如文档所说,“除非你需要支持打开http:、ftp:或file:以外的其他协议,否则你可能想使用FancyURLopener
。”
下面是一个简单的例子(足以让你入门,一旦你确定了自己想要和不想要的内容),使用的是BeautifulSoup:
import os
import urllib2
import urlparse
import bs4
def saveUrl(url):
page = urllib2.urlopen(url).read()
with open("file.html", "wb") as f:
f.write(page)
soup = bs4.BeautifulSoup(f)
for img in soup('img'):
imgurl = img['src']
imgpath = urlparse.urlparse(imgurl).path
imgpath = 'file.html_files/' + imgpath
os.makedirs(os.path.dirname(imgpath))
img = urllib2.urlopen(imgurl)
with open(imgpath, "wb") as f:
f.write(img)
saveUrl("http://emma-watson.net")
如果有任何图片使用了相对链接,这段代码就无法正常工作。为了解决这个问题,你需要调用urlparse.urljoin
来附加一个基础网址。而且,由于基础网址可以通过多种方式设置,如果你想处理任何人写的每个页面,你需要查阅文档并编写相应的代码。在这个时候,你可以开始考虑使用像scrapy
这样的工具。但如果你只想处理几个网站,写一些适合这些网站的代码就可以了。
同时,如果任何图片是通过JavaScript在页面加载后加载的——这在现代网站上很常见——那么除非你实际运行那段JavaScript代码,否则什么都无法工作。在这种情况下,你可能需要一个浏览器自动化工具,比如Selenium,或者一个浏览器模拟工具,比如Mechanize+PhantomJS,而不是一个抓取工具。