我正试图从URL中抓取输入框的值。我的XPath实现似乎有问题。
要刮取的页面看起来像:
<!DOCTYPE html>
<html lang="en">
<head></head>
<body>
<div><span>Blah</span></div>
<div><span>Blah</span> Blah</div>
<div>
<form method="POST" action="blah">
<input name="SomeName" id="SomeId" value="GET ME"/>
<input type="hidden" name="csrfToken" value="ajax:3575644127378754050" id="csrfToken-login">
</form>
</div>
</body>
</html>
我正试图这样解析它:
$Contents = file_get_contents("https://www.linkedin.com/uas/login");
$Selector = "//input[@id='csrfToken-login']/@value";
print_r($Selector);
$dom = new DOMDocument;
libxml_use_internal_errors(true);
$dom->loadHtml($Contents);
$xpath = new DOMXPath($dom);
libxml_use_internal_errors(false);
print_r($xpath->query($Selector));
注意:dump()
只是封装了print_r()
,但添加了一些堆栈跟踪信息和格式。
输出如下:
14:50:08 scraper.php 181: (Scraper->Test)
//input[@id='csrfToken-login']/@value
14:50:08 scraper.php 188: (Scraper->Test)
DOMNodeList Object
(
)
我认为这意味着它在文档中找不到与我的选择器匹配的任何内容?我已经尝试了很多变体,但看看我是否能找回东西:
/input/@value
/input
//input
/div
我唯一能从中获得任何的选择器是/
,它返回整个文档。
我做错了什么?
编辑:由于有些人无法用旧示例重现问题,我用一个几乎相同的示例替换了它,该示例也演示了问题,但使用了公共URL(LinkedIn登录页)。
有人认为这是不可能的,因为解析器被html5阻塞了——(就像内部页面一样)有人对此有任何经验吗?
如果选择器以单斜杠(/
)开头,则表示从根开始的绝对路径。您需要使用双斜线(//
)来选择所有匹配的元素,而不管它们的位置如何。
print_r对此不起作用。除了实际获得值之外,代码中的所有内容都很好。PHP中的列表类通常有一个名为length
的属性,请检查该属性。
$Contents = file_get_contents("https://www.linkedin.com/uas/login");
$Selector = "//input[@id='csrfToken-login']/@value";
$dom = new DOMDocument;
libxml_use_internal_errors(true);
$dom->loadHtml($Contents);
$xpath = new DOMXPath($dom);
libxml_use_internal_errors(false);
$b = $xpath->query($Selector);
echo $b->item(0)->value;
DOMXPath对我来说很好。
至于xpath,使用子代或自快捷方式//
来获取输入标签
//input[@id='SomeId']/@value
我访问过您指定的LinkedIn登录页面,但它格式不正确;即使您的精简示例也有一个未闭合的input
节点。我对PHP的XPath实现一无所知,但我猜没有一个直接的XPathneneneba API能够处理格式错误的文档。
顺便说一下,您的XPath是正确的。
在开始查询源代码之前,您可能需要使用TagSoup来"良好地形成"源代码的中间步骤,或者为任何特定于php的解决方案/实现使用Google"tag汤php"。
我希望这能有所帮助,
Zachary