我正在尝试学习python并创建一个Web实用程序。我想要完成的一项任务是创建一个可以在本地运行的单个html文件,但链接到它需要看起来像原始网页的所有内容。 (如果你要问为什么我想要这个,那是因为它可能是我正在创造的实用工具的一部分,或者如果没有,仅仅用于教育)所以我有两个问题,理论问题和实际问题: / p>
1)对于视觉(与功能相反)的目的,这是否可能?一个html页面可以脱机工作,同时链接到它在线所需的一切吗?或者如果他们的基本知识是让html文件本身在Web服务器上执行而不允许这样做?我能走多远?
2)我已经启动了一个python脚本,该脚本在html页面上去相关(将其中一个)链接元素,但我是一个菜鸟,所以我很可能错过了一些元素或属性,这些元素或属性也会链接到外部资源。我注意到在尝试几页后,下面的代码中的一个不能正常工作,它们似乎是一个没有正确链接的.js文件。 (即将出现的许多问题中的第一个)假设我的第一个问题的答案至少是部分答案,是否有人可以帮我修复本网站的代码?
谢谢。
更新,我错过了这个脚本标签,但即使我添加它之后仍然无法正常工作。
import lxml
import sys
from lxml import etree
from StringIO import StringIO
from lxml.html import fromstring, tostring
import urllib2
from urlparse import urljoin
site = "www.script-tutorials.com/advance-php-login-system-tutorial/"
output_filename = "output.html"
def download(site):
response = urllib2.urlopen("http://"+site)
html_input = response.read()
return html_input
def derealitivise(site, html_input):
active_html = lxml.html.fromstring(html_input)
for element in tags_to_derealitivise:
for tag in active_html.xpath(str(element+"[@"+"src"+"]")):
tag.attrib["src"] = urljoin("http://"+site, tag.attrib.get("src"))
for tag in active_html.xpath(str(element+"[@"+"href"+"]")):
tag.attrib["href"] = urljoin("http://"+site, tag.attrib.get("href"))
return lxml.html.tostring(active_html)
active_html = ""
tags_to_derealitivise = ("//img", "//a", "//link", "//embed", "//audio", "//video", "//script")
print "downloading..."
active_html = download(site)
active_html = derealitivise(site, active_html)
print "writing file..."
output_file = open (output_filename, "w")
output_file.write(active_html)
output_file.close()
此外,我可以通过检查所有元素来使代码更加完整......
看起来有点像这样,但我不知道迭代所有元素的确切方法。这是一个单独的问题,我很可能会在任何人回应时弄清楚......:
def derealitivise(site, html_input):
active_html = lxml.html.fromstring(html_input)
for element in active_html.xpath:
for tag in active_html.xpath(str(element+"[@"+"src"+"]")):
tag.attrib["src"] = urljoin("http://"+site, tag.attrib.get("src"))
for tag in active_html.xpath(str(element+"[@"+"href"+"]")):
tag.attrib["href"] = urljoin("http://"+site, tag.attrib.get("href"))
return lxml.html.tostring(active_html)
更新
感谢Burhan Khalid的解决方案,这看起来太简单了,乍一看不太可行,我让它发挥作用。代码非常简单,大多数人很可能不会要求它,但无论如何我都会发布它有帮助:
import lxml
import sys
from lxml import etree
from StringIO import StringIO
from lxml.html import fromstring, tostring
import urllib2
from urlparse import urljoin
site = "www.script-tutorials.com/advance-php-login-system-tutorial/"
output_filename = "output.html"
def download(site):
response = urllib2.urlopen(site)
html_input = response.read()
return html_input
def derealitivise(site, html_input):
active_html = html_input.replace('<head>', '<head> <base href='+site+'>')
return active_html
active_html = ""
print "downloading..."
active_html = download(site)
active_html = derealitivise(site, active_html)
print "writing file..."
output_file = open (output_filename, "w")
output_file.write(active_html)
output_file.close()
尽管如此,并且它非常简单,我在脚本中列出的网站上运行的.js对象仍然无法正确加载。有谁知道这是否可以解决?
答案 0 :(得分:1)
而我正在尝试使html文件脱机,同时使用 通过网络链接资源。
这是一个两步过程:
HEAD
部分添加BASE
标记,并将其href
属性指向绝对网址。既然你想学习如何自己动手,我会留下它。
答案 1 :(得分:0)
@Burhan在<base href="...">
中使用<head>
标记可以轻松回答,并且您可以找到它。我运行了你发布的脚本,页面下载得很好。正如您所注意到的,现在有些JavaScript失败了。这可能有多种原因。
如果您要将HTML文件作为本地file:///
网址打开,该页面可能无效。许多浏览器严重沙箱本地HTML文件,不允许它们执行网络请求或检查本地文件。
该页面可能会对远程站点执行XmlHTTPRequests
或其他网络操作,由于跨域脚本原因,这些操作将被拒绝。查看JS控制台,我发现您发布的脚本存在以下错误:
XMLHttpRequest cannot load http://www.script-tutorials.com/menus.php?give=menu. Origin http://localhost:8000 is not allowed by Access-Control-Allow-Origin.
不幸的是,如果您无法控制www.script-tutorials.com
,那么就没有简单的方法。