我一直在尝试使用PHP保存webpage部分的源代码。当我提取整个网页的内容时,保留了源代码顺序,但是当我尝试使用
获取文档的一部分时$dom = new DOMDocument;
$dom->loadHTML($webpage);
$xpath = new DOMXPath($dom);
$query_tag = "//div[contains(@class, 'class-name')]";
$result = $dom->saveHTML($xpath->query($query_tag)->item(0));
脚本标记搞砸了。到目前为止,这是发生此问题的唯一网站。我不知道saveHTML
函数有一些限制吗?
这是我应该收到的:
<div id="sponsored-category-header" class="page-header sponsored-category-header clear"> <script type="text/javascript">jQuery(document).ready(function($) {
var cat_head_params = {"sponsor":"SEO PowerSuite","sponsor_logo":"https:\/\/www.searchenginejournal.com\/wp-content\/plugins\/abm-sej\/includes\/category-images\/SPS_128.png","sponsor_text":"<div class=\"taxonomy-description\">Dominate Google local search results with ease! Get your copy of SEO PowerSuite and keep <a rel=\"nofollow\" href=\"http:\/\/sejr.nl\/PowerSuite-2016-5\" onClick=\"__gaTracker('send', 'event', 'Sponsored Category Click Var 1', 'Local Search', 'SEO PowerSuite');\" target=\"_blank\">your local SEO strategy<\/a> up to par.<\/div>","logo_url":"http:\/\/sejr.nl\/PowerSuite-2016-5","ga_labels":["Local Search","SEO PowerSuite"]}
$('#sponsored-category-header').append('<div class="sponsored-category-logo"></div>');
$('#sponsored-category-header .sponsored-category-logo').append(' <a rel="nofollow" href="'+cat_head_params.logo_url+'" onClick="__gaTracker(\'send\', \'event\', \'Sponsored Category Click Var 1\', \''+cat_head_params.ga_labels[0]+'\', \''+cat_head_params.ga_labels[0]+'\');" target="_blank"><img class="nopin" src="'+cat_head_params.sponsor_logo+'" width="96" height="96" /></a>');
$('#sponsored-category-header').append('<div class="sponsored-category-details"></div>');
$('#sponsored-category-header .sponsored-category-details').append('<h3 class="page-title sponsored-category-title">'+cat_head_params.sponsor+'</h3>');
$('#sponsored-category-header .sponsored-category-details').append(cat_head_params.sponsor_text);
});</script> </div>
这就是我实际得到的:
<div id="sponsored-category-header" class="page-header sponsored-category-header clear"> <script type="text/javascript">jQuery(document).ready(function($) {
var cat_head_params = {"sponsor":"SEO PowerSuite","sponsor_logo":"https:\/\/www.searchenginejournal.com\/wp-content\/plugins\/abm-sej\/includes\/category-images\/SPS_128.png","sponsor_text":"<div class=\"taxonomy-description\">Dominate Google local search results with ease! Get your copy of SEO PowerSuite and keep <a rel=\"nofollow\" href=\"http:\/\/sejr.nl\/PowerSuite-2016-5\" onClick=\"__gaTracker('send', 'event', 'Sponsored Category Click Var 1', 'Local Search', 'SEO PowerSuite');\" target=\"_blank\">your local SEO strategy<\/a> up to par.<\/div>","logo_url":"http:\/\/sejr.nl\/PowerSuite-2016-5","ga_labels":["Local Search","SEO PowerSuite"]}
$('#sponsored-category-header').append('<div class="sponsored-category-logo"></script>
</div>');
$('#sponsored-category-header .sponsored-category-logo').append(' <a rel="nofollow" href="'+cat_head_params.logo_url+'" onclick="__gaTracker(\'send\', \'event\', \'Sponsored Category Click Var 1\', \''+cat_head_params.ga_labels[0]+'\', \''+cat_head_params.ga_labels[0]+'\');" target="_blank"><img class="nopin" src="'+cat_head_params.sponsor_logo+'" width="96" height="96"></a>');
$('#sponsored-category-header').append('<div class="sponsored-category-details"></div>');
$('#sponsored-category-header .sponsored-category-details').append('<h3 class="page-title sponsored-category-title">'+cat_head_params.sponsor+'</h3>');
$('#sponsored-category-header .sponsored-category-details').append(cat_head_params.sponsor_text);
}); </div>
如果您错过了它,结尾的script
标记已向上移动几行。
为了清楚起见,我不是在谈论渲染的HTML。我在谈论发出请求后得到的实际源代码。任何有关如何解决此问题的帮助将不胜感激。
我知道函数saveHTML
导致了这个问题,因为当我通过PHP回显整个页面时,每个标记都在正确的位置。
答案 0 :(得分:1)
首先,您的代码应该触发一系列警告:
警告:DOMDocument :: loadHTML():htmlParseEntityRef:expecting';'在 实体
警告:DOMDocument :: loadHTML():意外的结束标记: 实体中强大警告:DOMDocument :: loadHTML():标记头 实体无效
这是期望使用野生HTML(并且此页面的代码也不是特别糟糕),但您甚至没有提到它,是什么让我怀疑您可能没有在开发框中启用错误报告。
此外,该页面包含大量JavaScript,而DOMDocument
只是一个HTML解析器。
有了这个,我们可以清楚地了解正在发生的事情。由于DOMDocument
不是一个成熟的浏览器,因此它无法理解JavaScript代码。这意味着它会检测到<script>
标记,但它不会将其内容作为JavaScript处理 - 它只是查找结束标记,而他找到的第一个标记是:
$('#sponsored-category-header').append('<div class="sponsored-category-logo"></div>');
^^^^^^
它不知道它是一个JavaScript字符串,应该被忽略。相反,它认为错误的标记正在关闭,因此它会尝试修复技术上无效的HTML并添加缺少的 </script>
标记。
出于这个确切的原因,<script>...</script>
标记集传统上是这样编写的:
<script type="text/javascript"><!--
var foo = '<p>Escaped end tag<\/p>';
//--></script>
...所以不知道JavaScript的用户代理可以安全地忽略整个标记(嘿,它只是一个很好的旧HTML评论)。然而,现在它几乎普遍被认为是不好的做法,因为“所有浏览器都理解JavaScript”。
最后注意:DOM扩展可能知道<script>
标记,并且知道不允许在其中包含其他标记。这就解释了为什么不考虑内部打开标签。