如何增强这个?获取另一个域中的网页的一部分

时间:2013-04-22 09:33:20

标签: php jquery html domdocument

我已经做到了:

<html>
    <head>
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
        <script>
            $(document).ready(
                function()
                {   
                    $("body").html($("#HomePageTabs_cont_3").html());
                }
            );
        </script>
    </head>
    <body>
    <?php
        echo file_get_contents("http://www.bankasya.com.tr/index.jsp");
    ?>

    </body>
</html>

当我用Firebug检查我的页面时,它会给出无数“丢失的文件”(图像,css文件,js文件等)错误。我想只有一部分页面不是全部。 此代码执行我想要的操作。但我想知道是否有更好的方法。

修改

该页面可以满足我的需求。我不需要所有的内容。所以iframe对我来说毫无用处。我只想要div #HomePageTabs_cont_3的原始数据。

3 个答案:

答案 0 :(得分:4)

最好的选择是PHP服务器端解析。我已经编写了一个小代码片段,告诉您如何使用DOMDocument(如果您的服务器拥有它,可能tidy来执行此操作,以解决所有格式错误的XHTML foos)。

警告:输出UTF-8。您可以在DOMDocument

的构造函数中更改此设置

警告2 barf out,如果它的输入既不是utf-8也不是iso-8859-9。当前页面的字符集是iso-8859-9,我认为他们没有理由改变它。

header("content-type: text/html; charset=utf-8");
$data = file_get_contents("http://www.bankasya.com.tr/index.jsp");
// Clean it up
if (class_exists("tidy")) {
   $dataTidy = new tidy();
   $dataTidy->parseString($data,
                                 array(
                                       "input-encoding" => "iso-8859-9",
                                       "output-encoding" => "iso-8859-9",
                                       "clean" => 1,
                                       "input-xml" => true,
                                       "output-xml" => true,
                                       "wrap" => 0,
                                       "anchor-as-name" => false
                                 )
                          );
   $dataTidy->cleanRepair();
   $data = (string)$dataTidy;
}
else {
    $do = true;
            while ($do) {
                    $start = stripos($data,'<script');
                    $stop = stripos($data,'</script>');
                    if ((is_numeric($start))&&(is_numeric($stop))) {
                            $s = substr($data,$start,$stop-$start);
                            $data = substr($data,0,$start).substr($data,($stop+strlen('</script>')));
                    } else {
                            $do = false;
                    }
            }
    // nbsp breaks it?
    $data = str_replace("&nbsp;"," ",$data);
    // Fixes for any element that requires a self-closing tag
    if (preg_match_all("/<(link|img)([^>]+)>/is",$data,$mt,PREG_SET_ORDER)) {
            foreach ($mt as $v) {
                    if (substr($v[2],-1) != "/") {
                            $data = str_replace($v[0],"<".$v[1].$v[2]."/>",$data);
                    }
            }
    }
    // Barf out the inline JS
    $data = preg_replace("/javascript:[^;]+/is","#",$data);
    // Barf out the noscripts
    $data = preg_replace("#<noscript>(.+?)</noscript>#is","",$data);
    // Muppets. Malformed comment = one more regexp when they could just learn to write proper HTML...
    $data = preg_replace("#<!--(.*?)--!?>#is","",$data);
}
$DOM = new \DOMDocument("1.0","utf-8");
$DOM->recover = true;
    function error_callback_xmlfunction($errno, $errstr) { throw new Exception($errstr); }
    $old = set_error_handler("error_callback_xmlfunction");
// Throw out all the XML namespaces (if any)
$data = preg_replace("#xmlns=[\"\']?([^\"\']+)[\"\']?#is","",(string)$data);
try {
      $DOM->loadXML(((substr($data, 0, 5) !== "<?xml") ? '<?xml version="1.0" encoding="utf-8"?>' : "").$data);
} catch (Exception $e) {
      $DOM->loadXML(((substr($data, 0, 5) !== "<?xml") ? '<?xml version="1.0" encoding="iso-8859-9"?>' : "").$data);
}
    restore_error_handler();
error_reporting(E_ALL);
$DOM->substituteEntities = true;
$xpath = new \DOMXPath($DOM);
echo $DOM->saveXML($xpath->query("//div[@id=\"HomePageTabs_cont_3\"]")->item(0));

按顺序出现:

  • 获取数据
  • 如果我们有tidy,请用它清理HTML
  • 创建一个新的DOMDocument并加载我们的文档((string)$dataTidy是一个简洁整洁的吸气剂)
  • 创建XPath请求路径
  • 使用XPath请求id设置为我们想要的所有div,获取集合的第一项(->item(0),这将是DOMElement)并请求DOM输出其XML内容(包括标签本身)

希望这是你正在寻找的......虽然你可能想把它包装在一个函数中。

修改

忘记提及:http://rescrape.it/rs.php了解实际的脚本输出!

编辑2

更正,该网站不是W3C有效的,因此,您需要tidy它或者在处理之前将一组正则表达式应用于输入。我要看看我是否可以制定一套来解决不一致问题。

编辑3

为所有没有tidy的人添加了修复程序。

编辑4

无法抗拒。如果您真的喜欢值而不是表格,请使用此而不是echo:

 $d = new stdClass();
 $rows = $xpath->query("//div[@id=\"HomePageTabs_cont_3\"]//tr");
 $rc = $rows->length;
 for ($i = 1; $i < $rc-1; $i++) {
     $cols = $xpath->query($rows->item($i)->getNodePath()."/td");
     $d->{$cols->item(0)->textContent} = array(
        ((float)$cols->item(1)->textContent),
        ((float)$cols->item(2)->textContent)
     );
 }

我不了解你,但对我来说,数据比格式错误的表更好。

(Welp,那个花了一段时间才写)

答案 1 :(得分:0)

我会与远程网站的所有者联系,询问是否有我可以使用的数据Feed,只会返回我想要的内容。

答案 2 :(得分:0)

Sébastien answer是最佳解决方案,但如果您想使用jquery,可以在网站的head部分添加Base代码,以避免在图片上找不到错误。

<base href="http://www.bankasya.com.tr/">

此外,您需要将源更改为绝对路径。

但请使用DOMDocument