使用简单的HTML DOM从标签中获取所有属性

6

Sort of a two part question but maybe one answers the other. I'm trying to get a piece of information out of an

<div id="foo">
<div class="bar"><a data1="xxxx" data2="xxxx" href="http://foo.bar">Inner text"</a>
<div class="bar2"><a data3="xxxx" data4="xxxx" href="http://foo.bar">more text"</a>

Here is what I'm using now.

$articles = array();
$html=file_get_html('http://foo.bar');
foreach($html->find('div[class=bar] a') as $a){
    $articles[] = array($a->href,$a->innertext);
}

This works perfectly to grab the href and the inner text from the first div class. I tried adding a $a->data1 to the foreach but that didn't work.

How do I grab those inner data tags at the same time I grab the href and innertext.

Also is there a good way to get both classes with one statement? I assume I could build the find off of the id and grab all the div information.

Thanks

4个回答

17

为了获取所有这些属性,你应该在调查解析后的元素之前进行操作,就像这样:

foreach($html->find('div[class=bar] a') as $a){
  var_dump($a->attr);
}

...并查看这些属性是否存在。它们似乎不是有效的HTML,因此解析器可能会将它们丢弃。

如果存在,您可以像这样读取它们:

foreach($html->find('div[class=bar] a') as $a){
  $article = array($a->href, $a->innertext);
  if (isset($a->attr['data1'])) {
    $article['data1'] = $a->attr['data1'];
  }
  if (isset($a->attr['data2'])) {
    $article['data2'] = $a->attr['data2'];
  }
  //...
  $articles[] = $article;
}

要同时获取这两个类,可以使用用逗号分隔的多个选择器:

foreach($html->find('div[class=bar] a, div[class=bar2] a') as $a){
...

1
另外,如果这两个类名确实都以相同的前缀(例如你的例子中的“bar”)开头,那么这个选择器也可能适用于你:div[class^=bar](意思是:类名以“bar”开头)。 - Fabian Schmengler
非常感谢。不过我不是很明白,我该怎么赋值呢?我的意思是,一旦我找到了多个div,我该怎么办?我还需要将其分配为“$a”吗?抱歉我有点迟钝。 - TheEditor
谢谢ermanbob。多重选择器很好用。我仍然无法获取自定义的<a>属性,实际上是data-content-id。我看了https://dev59.com/TGbWa4cB1Zd3GeqPcfYO,但我不确定该怎么做才能显示属性。我还看了http://stackoverflow.com/questions/11773940/how-to-get-the-value-of-special-attributes-custom-attributes-of-html-using-php,但使用它会返回错误。对于这两个问题,我都是使用$ html = file_get_html('http://foo.bar');行输入的。 - TheEditor
你提供的第一个链接非常有用。我再次编辑了我的答案,向你展示如何读取这些属性。 - ermannob
Ermannob非常感谢!我没有意识到我可以使用$a->attr! - TheEditor
我想更新一下,希望这是一个容易跟进的问题。在上面的例子中,foreach($html->find('div[class=bar] a, div[class=bar2] a') as $a){,我得到了我想要的数据。我用$article = array($a->href, $a->innertext);将其写入数组中(我在这里只是爬取Metafilter)。对于第一个选择器,只有一个匹配项,但对于第二个选择器,可能有多个匹配项。由于我将其写入单个数组中,因此它实际上无法使用,因为我无法将第二个选择器项与第一个关联起来。多维数组?我成功地让自己感到困惑了。谢谢。 - TheEditor

5

我知道这个问题已经很老了,但是提问者询问如何在一条语句中获取所有属性。我最近在做的一个项目中就用到了这个方法。

你可以通过 getAllAttributes() 方法获取元素的所有属性。结果会自动存储在名为 attr 的数组属性中。

在下面的示例中,我正在获取所有链接,但你可以将其用于任何你想要的地方。注意:这也适用于 data- 属性。因此,如果有一个名为 data-url 的属性,在运行 getAllAttributes 方法后,它将可通过 $e->attr['data-url'] 访问。

在你的情况下,你要查找的属性将是 $e->attr['data1']$e->attr['data2']。希望这能帮助到有需要的人。

获取所有属性

$html = file_get_html('somefile.html');
foreach ($html->find('a') as $e) {   //used a tag here, but use whatever you want
    $e->getAllAttributes();

    //testing that it worked
    print_r($e->attr);
}

2

请检查这段代码

<?php
$html = file_get_html('somefile.html');
foreach ($html->find('a') as $e) { 
$filter = $e->getAttribute('data-filter-string');
}
?>

2
仅有代码的答案质量较低。请编辑您的答案以解释您的代码。展示它是如何回答问题的,以及为什么。添加任何相关文档的链接。 - Stephen Ostermiller
万岁! 'attr' 给我返回了 PHP 致命错误。 使用 'getAttribute' 我让它工作了。 - PJunior
干净的解决方案,同样有效 - tony gil

2
$data1 = $html->find('.bar > a', 0)->attr['data1'];
$data2 = $html->find('.bar > a', 0)->attr['data2'];

1
请在您的代码中添加一些解释,以便其他人可以从中学习。 - Nico Haase

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