How to take values within multiple tags

Asked

Viewed 1,095 times

1

Hello,

I have the following HTML page:

<!DOCTYPE html>
<html>
<head>
    <title>Exemplo</title>
</head>
<body>
    <div id="text">Valor 1</div>
    <div id="text">Valor 2</div>
    <div id="text">Valor 3</div>
</body>
</html>

I’m using the following PHP function to pick up the text between a tag:

function capturar($string, $start, $end) {
    $str = explode($start, $string);
    $str = explode($end, $str[1]);
    return $str[0];
}

Example of use:

<?php
$url = file_get_contents('http://localhost/exemplo.html');
$valor = capturar($url, '<div id="text">', '</div>');
echo $valor;

However, when there is more than one identical tag with the text between them different, it only picks up the text between the first tag, what would I do to pick up all texts between that tag (<div id="text">, </div>) and add them between an array?

Thanks in advance.

  • 1

    Look id is a unique identifier, can not repeat on the same page

2 answers

-1

There are several ways to search for elements in an HTML document. First you should note that your HTML is invalid, because the attribute id should be unique throughout the document.

You can use queries Xpath to solve your problem:

$html = <<<'HTML'
<!DOCTYPE html>
<html>
<head>
    <title>Exemplo</title>
</head>
<body>
    <div id="text">Valor 1</div>
    <div id="text">Valor 2</div>
    <div id="text">Valor 3</div>
</body>
</html>
HTML;

$crawler = new DomDocument();
$crawler->loadHTML($html);
$xpath = new DOMXPath($crawler);

$elementos = $xpath->query("//div[@id='text']");

echo '<pre>';
foreach($elementos as $objeto) {
    var_dump($objeto->nodeValue);
}

Another way a little easier and that propricia you more resources is through third party libraries. A very powerful and useful library to Domcrawler.

To install using Composer:

composer require symfony/dom-crawler

Same solution as before, using DomCrawler:

require __DIR__ . '/vendor/autoload.php';

use Symfony\Component\DomCrawler\Crawler;

$html = <<<'HTML'
<!DOCTYPE html>
<html>
<head>
    <title>Exemplo</title>
</head>
<body>
    <div id="text">Valor 1</div>
    <div id="text">Valor 2</div>
    <div id="text">Valor 3</div>
</body>
</html>
HTML;

$crawler = new Crawler($html);

$elementos = $crawler->filterXPath("//div[@id='text']")->extract(['_text']);

echo '<pre>';
foreach($elementos as $elemento) {
   var_dump($elemento);
}

Note that in addition to this example, the documentation official still indicates that it is possible to use CSS selectors, including dependency symfony/css-selector.

-1

Ideal is to use preg_match_all.

function capturar($string, $start, $end) {

    $start = str_replace('/', '\/', $start);
    $end = str_replace('/', '\/', $end);
    preg_match_all('/'.$start.'(.*?)'.$end.'/', $string, $matches);
    if(isset($matches[1]))
        return $matches[1];
    else return false;
}

It may not be perfect, as you may need to "escape" to other characters. Now just do the /

Browser other questions tagged

You are not signed in. Login or sign up in order to post.