【问题标题】:Pull HTML content from remote website and display on page从远程网站拉取 HTML 内容并显示在页面上
【发布时间】:2013-06-04 01:41:28
【问题描述】:

现在已经在这方面工作了一段时间,我很难过。我试图从远程网站页面上的特定 div 中提取内容,然后将该 html 插入到我自己网站上的 div 中。我知道您不能单独使用 jQuery 的 .ajax、.load 或 .get 方法进行此类操作。

这是远程页面的 HTML:

<html>
    <body>
        <div class="entry-content">
            <table class="table">
                ...table #1 content...
                ...More table content...
            </table>
            <table class="table">
                ...table #2 content...
            </table>
            <table class="table">
                ...table #3 content...
            </table>
        </div>
    </body>
</html>

目标: 我正在尝试从远程页面的第一个表中获取 html。因此,在我的网站上,我希望获取以下 html 并将其放置在 id="fetched-html" 的 div 中:

<table class="table">
    ...table #1 content...
    ...More table content...
</table>

到目前为止,这是我使用 PHP 函数的地方:

<?php
function pullRaspi_SDImageTable() {
    $url = "http://www.raspberrypi.org/downloads";
    $curl = curl_init($url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    $output = curl_exec($curl);
    curl_close($curl);

    // Create new PHP DOM document
    $DOM = new DOMDocument;
    // Load html from curl request into document model
    $DOM->loadHTML($output);

    // Get 1st table
    $output = $DOM->firstChild->getElementsByTagName('table');

    return $output;
}
?>

我的本​​地网站页面上的最终结果应该是这样的:

<div id="fetched-html">
    <table class="table">
        ...table #1 content...
        ...More table content...
    </table>
</div>

这是另一个 PHP 函数的可能性吗?

<?php
function pullRaspPi_SDImageTable() {
    // Url to fetch
    $url = "http://www.raspberrypi.org/downloads";

    $ch = curl_init($url);
    $fp = fopen("raspberrypi_sdimagetable.txt", "w");
    curl_setopt($ch, CURLOPT_FILE, $fp);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);

    // Write html source to variable
    $rasp_sdimagetable = curl_exec($ch);

    // Close curl request
    curl_close($ch);

    return $rasp_sdimagetable;
}

// Then in the head of the html, add this jQuery:
<script type="text/javascript">
    $("#fetched-html").load("<?php pullRaspPi_SDImageTable(); ?> table.table:first");
</script>

问题是,这两个函数都不起作用。 :( 有什么想法吗?

【问题讨论】:

    标签: php jquery dom curl jquery-load


    【解决方案1】:

    使用simplehtmldom 从网站中提取 HTML 片段是一件轻而易举的事,然后您可以执行以下操作:

    function pullRaspi_SDImageTable() {
        $filename = '/tmp/downloads.html';  /// Where you want to cache the result
        $expiry = 600;  // 10 minutes
        $output = '';
    
        if (!file_exists($filename) ||  time() - $expiry > filemtime($filename)) {
            // There is no cache, so fetch the results from remote server
            require_once('simple_html_dom.php');
            $html = file_get_html('http://www.raspberrypi.org/downloads');
            foreach($html->find('div.entry-content table.table') as $elem) {
                    $output .= (string)$elem;
            }
    
            // Store the cache
            file_put_contents($filename, $output);
        } else {
            // Pull the content from the cahce
            $output = file_get_contents($filename);
        }
    
        return $output;
    }
    

    这会给你table.table HTML

    【讨论】:

    • 是的,感谢您的解决方案,但是 simplehtmldom 是如何工作的?这是一个 PHP 扩展吗?使用方法/函数将非标准的 html 解析为 PHP 会不会更慢并给服务器带来更多压力?这就是我尝试使用 cURL 路由的原因,因为我知道它是 PHP 内置的。任何有关 simplehtmldom 的更多信息将不胜感激!
    • 当然,比使用 DomDocument 的开销要多一些,因为这是一个用户态类,但它编写得很好,并且被许多项目使用。在这种情况下,它不会慢很多。从远程服务器(通过 curl 或其他任何方式)获取文档所需的时间是真正的负担。所以我会实现一个简单的文件缓存来缓存输出结果 10 分钟。当您的网站被多次点击时,这将为您提供最佳性能,因为后续请求将从缓存中转储。
    • 您能否指出正确的方向,如何实现简单的文件缓存并使用 simplehtmldom 或 DomDocument 模型缓存结果?对不起,我是一个 PHP 初学者。可能是这样的? http://davidwalsh.name/php-cache-function
    • 好@itsmejodie!非常感谢!几个更快速的问题......我怎么能只解析/选择获取的 html 中的第一个表?目前,我相信
      中的所有表格都正在被解析和显示,对吗?此外,在函数之前需要一次 simplehtmldom。这会给服务器带来很大的压力吗?每次有人点击页面并且函数运行时,我猜这个文件是重新加载的吗?或者,它是否在函数第一次运行时加载到内存中。因为 PHP 脚本是本地的,所以速度损失/应变可以忽略不计吗?
    • require_once() 放入缓存检查中,它只会发生一次。它只是一个 15KB 的类,所以我怀疑即使加载它也会对您的性能产​​生很大影响。更正每个表(带有类表)都被包括在内。如果你只想要第一个表,那么而不是foreach 只是做$elem = $html-&gt;find('div.entry-content')-&gt;find('table.table'); $output .= (string)$elem;
    【解决方案2】:

    您不能为此单独使用 jQuery 的 .ajax、.load 或 .get 方法 操作类型

    是的,您可以,但远程网站必须为此授予您授权。如果没有跨域限制,您只需插入 iframe 并使用正常的 DOM 功能即可。

    您只能使用 php 获得完整页面(使用常用函数 include、require 等并传递网站 URL,但同样情况,您需要获得授权..

    【讨论】:

      猜你喜欢
      相关资源
      最近更新 更多
      热门标签