我正在开展个人项目以离线查看网页。我想出的第一个想法是使用file_get_contents
来获取特定网址的内容,但这只获取html而不是该网页中的资源(css,图片,javascript等)。所以我必须编写正则表达式来获取页面中的样式表和图像:
$css_pattern = '/\S*\.css"/';
$img_src_pattern = '/src=(?:"|\')?.+\.(?:gif|jpg|png|jpeg)(?:"|\')/';
preg_match_all($css_pattern, $contents, $style_matches);
preg_match_all($img_src_pattern, $contents, $img_matches);
这有效但css中也有图像链接。我还在考虑如何处理这些问题。
还有像ganon
https://code.google.com/p/ganon/这样的项目和简单的html解析器可能会让我的生活更轻松,但我更喜欢使用正则表达式,因为我想了解更多相关信息。
问题是:有没有更好的方法来完成这个项目?该应用程序可能会有文件夹,用于保存每个站点的资产和html,它可能会变得笨拙。我听说过html5中的清单文件,但我不确定如果你不拥有该网站,那是否可行。有任何想法吗?如果没有其他方法可以做到这一点,那么也许你可以帮助我改进我上面的正则表达式。我基本上必须使用str_replace
和foreach
来获取样式表:
$stylesheets = array();
foreach($style_matches[0] as $match){
$stylesheets[] = str_replace(array('href=', '"', "'"), '', $match);
}
提前致谢!
答案 0 :(得分:2)
我更喜欢使用正则表达式,因为我想了解更多信息。
使用正则表达式解析HTML是可能的,尽管不是一件容易的事。以下论文给出了一个很好的介绍:
该论文中使用的正则表达式(REX)不是PHP(PCRE)中使用的正则表达式,但是如果你愿意学习,你应该能够理解它,它是相似的。
通过一些不错的测试用例,本文概述并在PHP中编写正则表达式应该是一个真正的训练营,可以让你深入研究正则表达式。
在正则表达式旁边,您还需要处理字符编码,这是其自身的另一个字段,然后采用解析器进行编码(如果在解析之前不进行重新编码)。
如果你正在寻找专门针对HTML 5兼容的解析器,它被指定为HTML 5“规范”的一部分,但是你不能用正常的表达式精确地做到这一点(至少到目前为止)据我所知):
对我来说,这种类型的解析看起来像是一个大量的开销,但是看看HTML 5 Parser的大纲,你就会明白你可以现在所有人都在为HTML解析而烦恼。看起来那些男人和女孩真的需要推动他们想象的任何东西。实际上以下引擎/浏览器都有HTML 5 Parser:
根据PHP生态系统的个人经验,没有那么多基于SGML /“松散”/低级/标签汤的HTML解析器。如果我写一个,我也会使用正则表达式进行字符串解析,REX浅层解析文章有一些很好的讨论。但是,我可能只会使用这样的低级HTML解析器为DOMDocument或其他一些验证/修复相关的东西制作任何HTML消费品,并且不会将它用于进一步的解析/文档抽象。 DOMDocument非常强大,特别是收集您在上面描述的链接。
对于您的其余问题,您可以找到在各种HTTP相关RFC中概述的所有元素,因此您需要自行决定要支持哪种链接解析算法以及如何重新映射静态CSS / image / js文件,如果再次保存它们。您通常会重新编写HTML以及哪些DOMDocument非常方便。
此外,您应该通过元元素在HTML文件中存储一些HTTP标头。特别是对于编码,除非你不重新编码它(这对于离线阅读无论如何都是有用的)。一些针对HTML创作的更一般的Q& A建议也适用于静态缓存。
html5 manifest file实际上是不同的东西。原始服务器应该支持它。情况可能并非如此(或者您需要构建它的解析器并处理它)。因此,如果您创建镜像,您可能还需要指出可以在本地存储以供脱机使用的所有静态资源。这是一个不错的主意,我还没有看到像wget这样的工具实现这一点,所以它可能值得用这个想法来实现。
您可能还与以下某种容器格式相关,而不是 HTML5清单文件:
这些格式/扩展中的另一个(此处:SingleFile Chrome扩展程序)根据维基百科使用Data URI scheme,这可能在这种情况下也很有用,虽然我不喜欢它,我会说它是最好有一种算法能够以可重现的方式将URL重新写入本地文件系统,这样您就可以使用相同的资产转储多个HTML文件,而无需多次获取资产。