【问题标题】:Getting DOM elements of html from file_get_contents [duplicate]从file_get_contents获取html的DOM元素[重复]
【发布时间】:2016-12-17 10:26:49
【问题描述】:

我正在使用 file_get_contents 从网站获取 html。我在 html 中有一个表(带有类名),我想在 html 标记中获取数据。

这就是我从 url 获取 html 数据的方式:

$url = 'http://example.com';
$content = file_get_contents($url);

html 看起来像:

<table class="space">
   <thead></thead>
   <tbody>
      <tr>
         <td class="marsia">1</td>
         <td class="mars">
           <div>Mars</div>
         </td>
      </tr>
      <tr>
         <td class="earthia">2</td>
         <td class="earth">
           <div>Earth</div>
         </td>
      </tr>
   </body>
</table>

有没有办法像在 jQuery 中一样在 php 中搜索 DOM 元素?这样我就可以在第二个 td 中访问值 1、2(第一个 td)和 div 的值。

类似

a) 在 html 中搜索具有类名称空间的表

b) 在该表内部,在 tbody 内部,返回每个 tr 的“第一个 td 值”和“div 在第二个 td 内的值”

所以我明白了; 1 和火星,2 和地球。

【问题讨论】:

标签: php html dom file-get-contents


【解决方案1】:

例如,使用DOM extension。它的DOMXPath 类对于此类任务特别有用。

您可以使用这样的 XPath 表达式轻松设置列出的条件:

//table[@class="space"]//tr[count(td) = 2]/td

在哪里 - //table[@class="space"] 从文档中选择所有具有class 属性值等于"space" 字符串的table 元素; - //tr[count(td) = 2] 选择所有具有两个 td 子元素的 tr 元素; - /td 代表td 元素。

示例实现:

$html = <<<'HTML'
<table class="space">
   <thead></thead>
   <tbody>
      <tr>
         <td class="marsia">1</td>
         <td class="mars">
           <div>Mars</div>
         </td>
      </tr>
      <tr>
         <td class="earthia">2</td>
         <td class="earth">
           <div>Earth</div>
         </td>
      </tr>
      <tr>
         <td class="earthia">3</td>
      </tr>
   </tbody>
</table>
HTML;

$doc = new DOMDocument;
$doc->loadHTML($html);

$xpath = new DOMXPath($doc);

$cells = $xpath->query('//table[@class="space"]//tr[count(td) = 2]/td');

$i = 0;
foreach ($cells as $td) {
  if (++$i % 2) {
    $number = $td->nodeValue;
  } else {
    $planet = trim($td->textContent);
    printf("%d: %s\n", $number, $planet);
  }
}

输出

1: Mars
2: Earth

上面的代码应该被视为一个示例,而不是实际使用的指令,因为它的可扩展性不是很好。逻辑与 XPath 表达式为每一行恰好选择两个单元格这一事实有关。在实践中,您可能希望选择行,对其进行迭代,并将额外的条件放入循环中,例如:

$rows = $xpath->query('//table[@class="space"]//tr');

foreach ($rows as $tr) {
  $cells = $xpath->query('.//td', $tr);

  if ($cells->length < 2) {
    continue;
  }

  $number = $cells[0]->nodeValue;
  $planet = trim($cells[1]->textContent);
  printf("%d: %s\n", $number, $planet);
}

DOMXPath::query() 使用相对于当前行 ($tr) 的 XPath 表达式调用,然后检查返回的 DOMNodeList 是否包含至少两个单元格。剩下的代码很简单。


您也可以使用SimpleXML 扩展,它也支持XPath。但与DOM 扩展相比,该扩展的灵活性要差得多。

对于大型文档,请使用基于基于 SAX 的解析器的扩展,例如 XMLReader

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-29
    • 1970-01-01
    • 2023-03-14
    • 2022-12-05
    • 2021-10-21
    • 2014-11-24
    • 2022-01-17
    • 1970-01-01
    相关资源
    最近更新 更多