【问题标题】:Unable to get table data from a html page无法从 html 页面获取表格数据
【发布时间】:2011-09-11 02:52:29
【问题描述】:

我正在尝试在 html 网页的表格中获取一些数据字段。该网页是在发布某些内容时动态生成的。我使用php-curl 获取网页,然后使用xpath 从某些字段获取数据。我能够获取页面而不是特定字段。代码是这样的

$url="http://www.rtu.ac.in/results/reformat.php";
$post="rollnumber=08epccs060&filename=fetchmodulesem_4_btech410m.php&button=Submit";
$ch=curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST,1);
curl_setopt($ch,CURLOPT_POSTFIELDS,$post);
curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
$content=curl_exec($ch);
curl_close($ch);

$totalPath="html/body/table[4]/tbody/tr[3]/td[4]";
$page=new DOMDocument();
$xpath=new DOMXPath($page);
$page->loadHTML($content);
$page->saveHTML();  // this shows the page contents

$total=$xpath->query($totalPath);
echo $total->length;    //shows 0
echo $total->item(0)->nodeValue;   //shows nothing

xpath 是正确的,因为我已经用FirePath 进行了检查。我从中了解到$xpath->query 不是在做工作。

【问题讨论】:

    标签: php html curl xpath web-scraping


    【解决方案1】:

    你写:

    echo $total->length;    //shows 0
    

    这意味着 xpath 返回了 0 个元素。所以它实际上并没有做你想做的事情。

    //html/body/table[4]/tr[3]/td[4]
    

    或者以其他方式检查您没有出错的 xpath 查询的语法。

    另外,我会先加载 HTML 文档,然后初始化 xpath 对象。

    $totalPath="//html/body/table[4]/tr[3]/td[4]";
    $page=new DOMDocument();
    $page->loadHTML($content);
    $xpath=new DOMXPath($page);    
    $total=$xpath->query($totalPath);
    

    编辑:按照 Wrikken 的建议删除了 tbody。

    编辑:启用错误报告,包括。警告,以便您可以确保 a) HTML 已正确加载到 DomDocument 中,并且 b) 如果您看到的 XPath 存在问题。


    让它运行。这是我的代码:

    <?php
    
    $url="http://www.rtu.ac.in/results/reformat.php";
    $post="rollnumber=08epccs060&filename=fetchmodulesem_4_btech410m.php&button=Submit";
    $ch=curl_init();
    curl_setopt($ch,CURLOPT_URL,$url);
    curl_setopt($ch,CURLOPT_POST,1);
    curl_setopt($ch,CURLOPT_POSTFIELDS,$post);
    curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1);
    curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
    $content=curl_exec($ch);
    curl_close($ch);
    
    echo 'Size: ', strlen($content), "\n";
    echo 'Beginning: ', substr($content, 0, 512), "\n\n";
    
    $page=new DOMDocument();
    $page->recover=false;
    $page->loadHTML($content);
    
    echo "\nLoaded XML:\n", $page->saveXML($page), "\n";
    
    
    $xpath=new DOMXPath($page);
    $totalPath="html/body/table[4]/tbody/tr[3]/td[4]";
    
    $paths = array(
        '//body',
        '//body/table',
        '//body/table[4]',
        '//body/table[4]/tr',
        '//body/table[4]/tr[3]',
        '//body/table[4]/tr[3]/td',
        '//body/table[4]/tr[3]/td[4]',
        '//html/body/table[4]/tr[3]/td[4]',
    );
    
    
    foreach($paths as $path) {
        $result=$xpath->query($path);
        echo $path, ': ', $result->length, "\n";
    }
    

    这是输出(剪切了仅用于加载验证的顶部输出):

    //body: 1
    //body/table: 4
    //body/table[4]: 1
    //body/table[4]/tr: 3
    //body/table[4]/tr[3]: 1
    //body/table[4]/tr[3]/td: 4
    //body/table[4]/tr[3]/td[4]: 1
    //html/body/table[4]/tr[3]/td[4]: 1
    

    总是返回一个长度,表示至少有一个节点。

    【讨论】:

    • @hakre: //html/body/table[4]/tr[3]/td[4] 也不起作用。我也试过//body/table[4]/tr[3]/td[4],但还是一样。为什么loadHTMLxpath 初始化的顺序会有所不同?
    • 为什么 loadHTML 和 xpath 初始化的顺序会有所不同? - 我不确定,但只是为了确保它不是错误的原因。如果我在一个空文档上初始化 xpath,那么我就无法查询任何东西。这就是它背后的想法,可能有一些优化,但我不确定这一点。所以它可以有所作为,但不能。只是想提供帮助。
    • @hakre: 不,订单没有任何区别,我之前写过这样的代码来从其他一些网站获取内容,它在那里工作
    • @lovesh:您尝试加载的 HTML 使用 DomDocument 失败。我假设它是空的,所以你无论如何都不能查询它。最好做适当的错误检查。我认为 xpath 是现在寻找错误的错误点。
    • @lovesh:在处理变量之前查看变量以验证它们是否包含您期望的内容:var_dump()print_r() 对此很有帮助。然后阅读警告,它们通常包含对可能犯的小错误的重要提示。学习一门语言总是一步一步。做一些微小的步骤并从手册中收集尽可能多的信息。
    【解决方案2】:

    不查看 HTML:/tbody 不存在,只是由 Firefox 添加。删除该部分,并对该工具产生健康的不信任;)


    编辑

    事实上,顺序应该是:

    $page=new DOMDocument();
    $page->loadHTML($content);
    $xpath=new DOMXPath($page);
    

    当 DOMXpath 拍摄快照时,它不会跟踪之后的 DOM 更改。

    【讨论】:

    • 你的意思是我的xpath应该是这样的$totalPath="html/body/table[4]/tr[3]/td[4]";
    • 是的,可能在html 之前有一个/(我使用DOMXPath 已经有一段时间了),但是是的,就是这样。
    • firefox 没有插入tbody 我已经通过firebuginspect element 检查了html 源代码,并且tbody 存在于html 中。我也尝试从我的 xpath 中删除tbody,但输出仍然没有变化。你能在浏览器中运行我的代码并检查吗?我正在使用 Firefox 4
    • sigh 它确实添加了tbody。不要相信 DOM 浏览器。下载html,用记事本打开。 Firebug 的 DOM 浏览器是 Firefox 经过各种调整后的结果。再说一次,还有另一个问题:您应该使用loadHTML before 创建DOMXPath(它实际上使用了该点的快照,并且不知道之后DOM中的更改。这样做,/html/body/table[4]/tr[3]/td[4] 没有 /tbody 就可以了。
    • 可以确认它在没有 /tbody 的情况下工作。将我的测试脚本和输出添加到我的答案中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多