Question

Je suis en train d'écrire un script PHP qui consiste à gratter des pages web.Actuellement, le script analyse de la page, ligne par ligne, mais il casse si il y a une balise qui s'étend sur plusieurs lignes, comme

<img src="example.jpg"
alt="example">

Si le pire arrive au pire, je pourrais peut-être prétraitement de la page en supprimant tous les sauts de ligne, puis de le ré-insertion sur le plus proche >, mais cela semble être une bidouille.

Dans l'idéal, j'aimerais être capable de détecter une balise qui s'étend sur les lignes, les relier des lignes, et de continuer le traitement.
Quelle est donc la meilleure méthode pour détecter ce?

Était-ce utile?

La solution 4

Peut-être pour les futurs projets, je vais utiliser une analyse de la bibliothèque, mais c'est un peu à côté de la question à portée de main.C'est ma solution actuelle. rstrpos est strpos, mais de sens inverse.Exemple d'utilisation:

for($i=0; $i<count($lines); $i++)
{
    $line = handle_mulitline_tags(&$i, $line, $lines);
}

Et voici que la mise en œuvre:

function rstrpos($string, $charToFind, $relativePos)
{
    $searchPos = $relativePos;
    $searchChar = '';

    while (($searchChar != $charToFind)&&($searchPos>-1))
    {
        $newPos = $searchPos-1;
        $searchChar = substr($string,$newPos,strlen($charToFind));
        $searchPos = $newPos;
    }

    if (!empty($searchChar))
    {
        return $searchPos;
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}

function handle_multiline_tags(&$i, $line, $lines)
{
    //if a tag is opened but not closed before a line break,

    $open = rstrpos($line, '<', strlen($line));
    $close = rstrpos($line, '>', strlen($line));
    if(($open > $close)&&($open > -1)&&($close > -1))
    {
        $i++;
        return trim($line).trim(handle_multiline_tags(&$i, $lines[$i], $lines));
    }
    else
    {
        return trim($line);
    }
}

Cela pourrait être optimisé, d'une certaine façon, mais pour ma part, c'est suffisant.

Autres conseils

C'est une de mes bêtes noires: jamais analyser HTML à la main. Jamais analyser HTML avec les expressions régulières. Jamais analyser HTML avec des comparaisons de chaînes. Toujours l'utilisation d'un analyseur HTML pour analyser HTML – c'est qu'ils sont là.

Il a été un long temps depuis que j'ai fait du PHP, mais une recherche rapide activé cette PHP5, HTML parser.

Ne pas écrire un analyseur, l'utilisation de quelqu'un d'autre: DOMDocument::loadHTML - c'est juste, je pense qu'il y a beaucoup d'autres.

Eh bien, ce n'est pas de répondre à la question et il est de plus en plus une opinion, mais...

Je pense que la meilleure stratégie de grattage (et, par conséquent, d'éliminer ce problème) n'est pas d'analyser HTML, ligne par ligne, ce qui n'est pas naturel du HTML, mais de l'analyser par son naturel délimiteur:<> les paires.

Il y aura deux types de cours:

  • Tag éléments qui sont immédiatement fermés, par exemple, < br />
  • Tag éléments qui ont besoin d'une balise de fermeture séparée, par exemple, < p > texte < /p >

Vous pouvez immédiatement voir l'avantage de l'utilisation de cette stratégie dans le cas de l'alinéa(p) tags:Il sera plus facile à analyser mutiline paragraphes au lieu d'avoir à suivre lorsque la balise de fermeture est.

Pourquoi n'avez-vous pas lu dans une ligne, et de définir une chaîne de caractères, puis vérifier la chaîne pour la balise d'ouvertures et de fermetures, Si une balise s'étend sur plus d'une ligne ajoutez la ligne suivante à la chaîne et de déplacer la partie avant de l'accolade d'ouverture de votre traitées de la chaîne.Puis il suffit d'analyser l'intégralité du fichier en faisant cela.Son pas beau, mais il devrait fonctionner.

Si tu dois t'en tenir à votre méthode actuelle de l'analyse, et c'est une regex, vous pouvez utiliser le multi-indicateur de ligne "m" pour s'étendre sur plusieurs lignes.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top