从外部网站获取DIV内容

22

我想用纯PHP从外部网站获取一个DIV。

外部网站:http://www.isitdownrightnow.com/youtube.com.html

我想要的来自isitdownrightnow(statusup div)的div文本是:<div class="statusup">The website is probably down just for you...</div>

我已经尝试过使用file_get_contentsDOMDocumentstr_get_html,但是我无法让它正常工作。

例如这个:

$page = file_get_contents('http://css-tricks.com/forums/topic/jquery-selector-div-variable/');
    $doc = new DOMDocument();
    $doc->loadHTML($page);
    $divs = $doc->getElementsByTagName('div');
    foreach($divs as $div) {
        // Loop through the DIVs looking for one withan id of "content"
        // Then echo out its contents (pardon the pun)
        if ($div->getAttribute('class') === 'bbp-template-notice') {
             echo $div->nodeValue;
        }
    }

它只会在控制台显示一个错误:

未能加载资源:服务器响应状态为500(内部服务器错误)


3
你需要展示你具体遇到的问题,否则我们无法提供帮助。"我不能让它工作"不是一个有效的问题描述。请提供更详细的信息。 - PeeHaa
1
@PeeHaa 那是针对不同的 URL。如果他那样做了,它会起作用,但问题中的确切 URL 不会。 - markasoftware
1
OP并没有说他想要使用那个URI,他只是想要结果。 - PeeHaa
1
谢谢大家的回答。实际上我只是选择这个网站作为例子,因为我自己在网上没有任何东西。它也可以是任何其他网站,甚至是一个简单的HTML文件。@PeeHaa 我删除了它,因为它变得非常混乱,大多数情况下,如果我要回显我的结果,它只是空白。 - Kallewallex
@mightyuhu,第二个我添加的(css-tricks.com)怎么样?它可以是任何URL。我没有在做项目或类似的事情。只是想学一点PHP。 - Kallewallex
显示剩余10条评论
4个回答

65

这是我一直使用的方法:

$url = 'https://somedomain.com/somesite/';
$content = file_get_contents($url);
$first_step = explode( '<div id="thediv">' , $content );
$second_step = explode("</div>" , $first_step[1] );

echo $second_step[0];

1
它在一些网站上对我有效。但是在我试图获取的网站上却不起作用...有什么想法吗? - Kallewallex
1
我无法确定域名,但是有可能当你使用这个而不是访问域名时,你想要获取的内容没有被生成。你可以尝试使用HTTP客户端/调试器进行实验。我正在使用Paw http。只需尝试一个请求并更改头信息。然后你就可以看到输出并检查你的div内容是否被显示。 - zk_mars
1
最后。好的。我试了一下。只有在修改标题时才会显示div。非常感谢。 - Kallewallex
有比字符串操作更好的方法来完成这个任务。如果他们在HTML中添加了一个新类,或进行任何小的调整,那么你就会遇到麻烦。尝试使用goutte https://github.com/FriendsOfPHP/Goutte - Phil Sturgeon
3
如果子内容有多个div并且还有多个闭合div,那怎么办呢?(代码针对单个div是正确的,但需要适用于多个div) - Hiren Kubavat

18
这可能有点过头了,但你会明白要点。
<?php 

$doc = new DOMDocument;

// We don't want to bother with white spaces
$doc->preserveWhiteSpace = false;

// Most HTML Developers are chimps and produce invalid markup...
$doc->strictErrorChecking = false;
$doc->recover = true;

$doc->loadHTMLFile('http://www.isitdownrightnow.com/check.php?domain=youtube.com');

$xpath = new DOMXPath($doc);

$query = "//div[@class='statusup']";

$entries = $xpath->query($query);
var_dump($entries->item(0)->textContent);

?>

这真的有效。太棒了。我怎么才能得到没有 "string(XX)" 的文本并将其放入变量中? - Kallewallex
2
将 var_dump 更改为类似于 $var = $entries->item(0)->textContent 的赋值语句。 - worenga
1
非常感谢。就是这样。我试着调整了一下......但是我在其他网站上使用它时真的很困难,有时候它能正常工作,有时候却不能。例如,我正在尝试获取一个div <h2 id="place-one" class="success">Yes.</h2> 但是使用 "//h2[@class='success']"; 却没有起作用。 - Kallewallex
很难在没有更多关于特定URL的详细信息的情况下说出来。 - worenga
3
$var = $xpath->evaluate('string(//div[@class="startup"])'); 这行代码会直接返回文本内容,以字符串形式呈现。 - ThW
显示剩余3条评论

3
我使用了@mightyuhu提出的xpath方法,并且在他的添加的赋值语句下它表现得非常好。根据你所获取信息的网页和标签的'ID'或者'class'的可用性,你将需要改变所使用的查询方式。如果这个标签有一个被指定的'ID',你可以使用这个(以下示例是用于提取美元汇率的): $query = "//div[@id='USD']"; 然而,网站开发者不会让我们如此轻松,所以在我的例子中会有更多的“未命名”标签需要深入挖掘。
<div id="USD" class="tab">
  <table cellspacing="0" cellpadding="0">
    <tbody>
     <tr>
        <td>Ask Rate</td>
        <td align="right">1.77400</td>
     </tr>
     <tr class="even">
        <td>Bid Rate</td>
        <td align="right">1.70370</td>
     </tr>
     <tr>
        <td>BNB Fixing</td>
        <td align="right">1.735740</td>
     </tr>
   </tbody>
  </table>
</div>

所以我不得不更改查询以获取“询问费率”:

$doc->loadHTMLFile('http://www.fibank.bg/en');
$xpath = new DOMXPath($doc);
$query = "//div[@id='USD']/table/tbody/tr/td";

所以,我使用了上面的查询,但将 item 更改为1,而不是0,以获取汇率所在的第二列(第一列包含文本“询价率”):

$entries = $xpath->query($query);
$usdrate = $entries->item(1)->textContent;

另一种方法是直接在查询中引用值,在没有名称或样式时,应该使用标签索引来完成。这是我从我的Maxthon浏览器和其“检查元素”功能以及“复制XPath”右键菜单选项中获得的知识(很不错,对吧?):

"//*[@id="USD"]/table/tbody/tr[1]/td[2]"

注意它在//后面插入了一个星号(*),我没有深入研究。在这种情况下,您应该再次使用item(0)获取值,因为没有其他值。
如果需要,您可以对提取的字符串进行任何更改,例如更改数字格式以匹配您的偏好:
$usdrate = number_format($usdrate, 5, ',', ' ');

我希望这篇文章能对有需要的人有所帮助,就像我在上面找到答案一样,它可以节省别人查找正确查询和语法的时间。


-3
$contents = file_get_contents($url); 

  $title = explode('<div class="entry-content">',$contents); 
  $title = explode("</div>",$title[1]); 

$fp = fopen ("s.php", "w+"); 
fwrite ($fp, "$title[0]"); 
fclose ($fp); 
require_once('s.php'); 

你为什么要使用fopen/fwrite/require_once?而且,你重复了已接受的答案..? - Sjon
2
感谢您回答这个问题!在 Stack Overflow 上,我们不鼓励仅包含代码的答案,因为原始提问者(或未来的读者)可能难以理解其背后的逻辑。请编辑您的答案并包含对代码的解释,以便其他人可以从中受益。谢谢! - Maximillian Laumeister

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接