Vous n'êtes pas identifié(e).

  • Contributions :
  • Vos boîtes de messages privés sont vides.

🟣 [Question PHP] Modifier html à la volée avec Simple HTML DOM


#21 2016-02-17 11:58:35

Mention DevForEver
🥉 Grade : Scout

AuxiliaireIngénieur web10likes
Lieu : Alsace
Inscription : 2016-02-16
Messages : 178
Likes : 12

PHP
JAVA
DB Admin
Sécurité

Re : [Question PHP] Modifier html à la volée avec Simple HTML DOM

include('simple_html_dom.php');
$html = new simple_html_dom();
$html = file_get_html('http://www.site-web.com');
foreach ($html->find('h2') as $h2) {
$h2->plaintext = 'hello world';
}

Sauf que si je ne m'abuse, les nouvelles valeurs n'affectent pas le dom original. En effet si j'explore le dom à nouveau, je me rends compte qu'il n'a pas changé et je retrouve les valeurs d'origine des h2.

Info: foreach est un itérateur en lecteur seule, il n'est pas possible de modifier la valeur de $h2. Pour rendre $h2 modifiable, il convient de définir la boucle ainsi: foreach ($html->find('h2') as &$h2)

Si la méthode avec xpath marche, touche à rien big_smile

Si vraiment, tu veux rendre le script moins gourmand la solution est de parcourir qu'une seule fois l'ensemble du code HTML (xPath parcourt l'ensemble de caractère à chaque fois) et de de faire les remplacements à la volée.

Pour ce faire, une solution est de parcourir le code HTML, détecter les zones à remplacer, copier ce qui ne change pas, insérer le nouveau contenu et ainsi de suite.
Au final, on se retrouve avec le code HTML original et un code HTML où les textes ont été remplacés.

0
J'aime ❤️

🔴 Hors ligne

#22 2016-02-17 12:15:44

Mention Walid
🥉 Grade : Scout

Auxiliaire1000 messagesMembre Hospitalier
Inscription : 2013-02-07
Messages : 1 293
Likes : 2

Sémantique

Re : [Question PHP] Modifier html à la volée avec Simple HTML DOM

DevForEver a écrit :

Info: foreach est un itérateur en lecteur seule, il n'est pas possible de modifier la valeur de $h2. Pour rendre $h2 modifiable, il convient de définir la boucle ainsi: foreach ($html->find('h2') as &$h2)

tu utilises vraiment simple html dom ? cela marche très bien avec  foreach ($html->find('h2') as $h2){}

Le problème est la méthode appelée dans le foreach, pas le foreach lui même. $h2->plaintext() ne changera pas l'objet dom $html par contre avec $h2->innertext = 'hello world'; Le dom $html est bel et bien modifié, même dans un foreach.

Je ne vois pas ce que tu veux dire par un itérateur en lecture seule, pour moi c'est un itérateur point. En effet tu peux modifier toutes les valeurs d'un array en passant par un foreach. Du coup je ne comprends pas ce que tu as voulu dire.

DevForEver a écrit :

Si vraiment, tu veux rendre le script moins gourmand la solution est de parcourir qu'une seule fois l'ensemble du code HTML (xPath parcourt l'ensemble de caractère à chaque fois) et de de faire les remplacements à la volée.

C'est exactement ce que je fais, je ne parcours qu'une seule fois chaque noeud de de l'objet simple_html_dom

DevForEver a écrit :

Pour ce faire, une solution est de parcourir le code HTML, détecter les zones à remplacer, copier ce qui ne change pas, insérer le nouveau contenu et ainsi de suite.

Comment faire ça était effectivement le problème à résoudre smile

0
J'aime ❤️

🔴 Hors ligne

#23 2016-02-17 13:48:46

Mention ciboulette
🥉 Grade : Scout

Auxiliaire
Inscription : 2015-11-01
Messages : 391
Likes : 5

Re : [Question PHP] Modifier html à la volée avec Simple HTML DOM

moi sur le site de Bigorno avec un replace de SEO par Bigorno le script d'execute en :

1 fois en 0.798 sec  sur un PHP5.
10 fois 6.088 sec sur un PHP5

1 fois en 0.698 sec sur un PHP7
10 fois en 6.011 sec sur un PHP7

sur la page WIKI (https://fr.wikipedia.org/wiki/Optimisation_pour_les_moteurs_de_recherche) avec un replace de SEO par Bigorno le script d'execute en :

1 fois en 0.114 sec sur un PHP5
10 fois en 0.964 sec sur un PHP5

1 fois en  0.104 sec sur un PHP7
10 fois en 1.015 sec sur un PHP7

ce qu'on peu voir donc la c'est que le script n'est pas forcement gourmand mais c'est plutôt la vitesse du serveur en face qui va jouer ...

Ma version de test :

<?php
$timestart=microtime(true);
$output = array();
$total_execute = 10;


for ($i = 1; $i <= $total_execute; $i++) {
   
    $doc = new DOMDocument;
    @$doc->loadHTMLFile('https://fr.wikipedia.org/wiki/Optimisation_pour_les_moteurs_de_recherche');
    $xpath = new DOMXPath($doc);
    $nodes = $xpath->query('//text()');
    foreach ($nodes as $node) {
      $node->nodeValue = str_replace("SEO", "Bigorno", $node->nodeValue);
    }

    $output[] = $doc->saveHTML();
}

echo "<br>Script execute en " . number_format((microtime(true)-$timestart), 3) . " sec";
 

Apres oui le script peu etre plus gourmand selon la fonction de SPIN utilisé smile, mais je sais pas le debit que tu demande

0
J'aime ❤️

🔴 Hors ligne

#24 2016-02-17 14:23:47

Mention Walid
🥉 Grade : Scout

Auxiliaire1000 messagesMembre Hospitalier
Inscription : 2013-02-07
Messages : 1 293
Likes : 2

Sémantique

Re : [Question PHP] Modifier html à la volée avec Simple HTML DOM

ciboulette a écrit :

moi sur le site de Bigorno avec un replace de SEO par Bigorno le script d'execute en :

1 fois en 0.798 sec  sur un PHP5.
10 fois 6.088 sec sur un PHP5

1 fois en 0.698 sec sur un PHP7
10 fois en 6.011 sec sur un PHP7

sur la page WIKI (https://fr.wikipedia.org/wiki/Optimisation_pour_les_moteurs_de_recherche) avec un replace de SEO par Bigorno le script d'execute en :

1 fois en 0.114 sec sur un PHP5
10 fois en 0.964 sec sur un PHP5

1 fois en  0.104 sec sur un PHP7
10 fois en 1.015 sec sur un PHP7

ce qu'on peu voir donc la c'est que le script n'est pas forcement gourmand mais c'est plutôt la vitesse du serveur en face qui va jouer ...

Ma version de test :

<?php
$timestart=microtime(true);
$output = array();
$total_execute = 10;


for ($i = 1; $i <= $total_execute; $i++) {
   
    $doc = new DOMDocument;
    @$doc->loadHTMLFile('https://fr.wikipedia.org/wiki/Optimisation_pour_les_moteurs_de_recherche');
    $xpath = new DOMXPath($doc);
    $nodes = $xpath->query('//text()');
    foreach ($nodes as $node) {
      $node->nodeValue = str_replace("SEO", "Bigorno", $node->nodeValue);
    }

    $output[] = $doc->saveHTML();
}

echo "<br>Script execute en " . number_format((microtime(true)-$timestart), 3) . " sec";
 

Apres oui le script peu etre plus gourmand selon la fonction de SPIN utilisé smile, mais je sais pas le debit que tu demande

On s'est pas compris, je disais pas que ton script était gourmand, le mien aussi traverse le dom, et quoi qu'il arrive c'est une méthode gourmande, bien optimiser la méthode de parsing est essentiel.

Si cela t'intéresse relis les problématiques que j'ai posté plus haut tu constateras que ta fonction de replacement ne marchera pas dans le cas d'utilisation dont j'ai parlé.

Sincèrement, je ne connais pas bien la classe domNode mais d'après ce que je vois sur la doc $node->nodevalue va te donner le plain text de node en question, mais aussi celui de ces enfants. Donc si j'ai <p>Salut <strong>les dev</strong></p>, lorsque je vais agir le plaintext du node correspondant à la balise <p>, je vais agir sur "salut les dev" sauf que j'aurai perdu les <strong></strong>


= 'hello world' va agir


Le contenu textuel de ce noeud et de ces descendants.

0
J'aime ❤️

🔴 Hors ligne

#25 2016-02-17 14:41:44

Mention ciboulette
🥉 Grade : Scout

Auxiliaire
Inscription : 2015-11-01
Messages : 391
Likes : 5

Re : [Question PHP] Modifier html à la volée avec Simple HTML DOM

Bigorno a écrit :

Sincèrement, je ne connais pas bien la classe domNode mais d'après ce que je vois sur la doc $node->nodevalue va te donner le plain text de node en question, mais aussi celui de ces enfants. Donc si j'ai <p>Salut <strong>les dev</strong></p>, lorsque je vais agir le plaintext du node correspondant à la balise <p>, je vais agir sur "salut les dev" sauf que j'aurai perdu les <strong></strong>

Le contenu textuel de ce noeud et de ces descendants.

Non la preuve :

Fichier source : http://www.woozy.fr/source.html

url du test : http://www.woozy.fr/test.php


Code :


    $doc = new DOMDocument;
    @$doc->loadHTMLFile('http://www.woozy.fr/source.html');
    $xpath = new DOMXPath($doc);
    $nodes = $xpath->query('//text()');
    foreach ($nodes as $node) {
      $node->nodeValue = str_replace("dev", "Bigorno", $node->nodeValue);
$node->nodeValue = str_replace("Salut", "Coucou", $node->nodeValue);
    }

    $output =  $doc->saveHTML();

 

Dernière modification par ciboulette (2016-02-17 15:45:53)

0
J'aime ❤️

🔴 Hors ligne

#26 2016-02-17 15:20:19

Mention DevForEver
🥉 Grade : Scout

AuxiliaireIngénieur web10likes
Lieu : Alsace
Inscription : 2016-02-16
Messages : 178
Likes : 12

PHP
JAVA
DB Admin
Sécurité

Re : [Question PHP] Modifier html à la volée avec Simple HTML DOM

Je ne vois pas ce que tu veux dire par un itérateur en lecture seule, pour moi c'est un itérateur point. En effet tu peux modifier toutes les valeurs d'un array en passant par un foreach. Du coup je ne comprends pas ce que tu as voulu dire.

<?php
//itinéation en lecteur seule
$N = array(1, 2, 3);
$i = 0;
foreach ($N as $n) {
    $n = $i;
}
print_r($N);

//itinéation en lecteur/écriture
$N = array(1, 2, 3);
$i = 0;
foreach ($N as &$n) {
    $n = $i;
}
print_r($N);
?>

Array
(
    [0] => 1
    [1] => 2
    [2] => 3
)
Array
(
    [0] => 0
    [1] => 0
    [2] => 0
)

 

Dans ton cas, foreach remplace les valeurs car les variables ne sont pas les mêmes dans l'array à parcourir et la valeur à fixer.


C'est exactement ce que je fais, je ne parcours qu'une seule fois chaque noeud de de l'objet simple_html_dom

function parse($html){
      foreach($html->find('*') as $key => $tag){
        $array = $tag->children(-1);
        if ($array){
          parse($tag);
...
 

A vérifier, $html->find('*') parcourt à chaque fois l'ensemble du code HTML pour trouver les nodes.
Mets voir un compteur dans ta boucle pour trouver le nombre de fois où $html->find('*') est lancé.

tu utilises vraiment simple html dom ?
Comment faire ça était effectivement le problème à résoudre

J'utilise très rarement simple html dom et cie car bien souvent le code HTML des sites web est crade ou l'encode est foireux. Et donc le parseur HTML part en sucette.
La méthode en une passe utilise strpos pour trouver le début et la fin des tags HTML puis substr pour copier le code qui ne change pas. Pas sûr que cela apporte beaucoup dans le cas de spin hormis un défi de geek pour qques mses big_smile

0
J'aime ❤️

🔴 Hors ligne

#27 2016-02-18 13:26:18

Mention Walid
🥉 Grade : Scout

Auxiliaire1000 messagesMembre Hospitalier
Inscription : 2013-02-07
Messages : 1 293
Likes : 2

Sémantique

Re : [Question PHP] Modifier html à la volée avec Simple HTML DOM

ciboulette a écrit :
Bigorno a écrit :

Sincèrement, je ne connais pas bien la classe domNode mais d'après ce que je vois sur la doc $node->nodevalue va te donner le plain text de node en question, mais aussi celui de ces enfants. Donc si j'ai <p>Salut <strong>les dev</strong></p>, lorsque je vais agir le plaintext du node correspondant à la balise <p>, je vais agir sur "salut les dev" sauf que j'aurai perdu les <strong></strong>

Le contenu textuel de ce noeud et de ces descendants.

Non la preuve :

Fichier source : http://www.woozy.fr/source.html

url du test : http://www.woozy.fr/test.php


Code :


    $doc = new DOMDocument;
    @$doc->loadHTMLFile('http://www.woozy.fr/source.html');
    $xpath = new DOMXPath($doc);
    $nodes = $xpath->query('//text()');
    foreach ($nodes as $node) {
      $node->nodeValue = str_replace("dev", "Bigorno", $node->nodeValue);
$node->nodeValue = str_replace("Salut", "Coucou", $node->nodeValue);
    }

    $output =  $doc->saveHTML();

 

Merci Ciboulette de m'avoir contacté sur skype

J'ai vérifier le test qui l'a mis en place et cela fonctionne parfaitement, sur deux remplacements, c'est très rapide, je vais tester grandeur nature pour me faire une idée définitive, mais tout porte à croire que c'est largement mieux que la méthode que j'ai utilisé. Je vous tiens au courant.

0
J'aime ❤️

🔴 Hors ligne

#28 2016-10-19 13:17:43

Mention Walid
🥉 Grade : Scout

Auxiliaire1000 messagesMembre Hospitalier
Inscription : 2013-02-07
Messages : 1 293
Likes : 2

Sémantique

Re : [Question PHP] Modifier html à la volée avec Simple HTML DOM

Hello, moi je fais encore du simple html dom, mais ciboulette ma montré comment il faisait avec dom document et xpath et ça marche très bien, même beaucoup plus rapide.

comme j'ai réussi à faire ce que je voulais, je me suis arrêté à simple html dom, mais pour faire les choses bien, je devrai utiliser la méthode proposée par ciboulette

Dernière modification par Walid (2016-10-19 13:20:29)

0
J'aime ❤️

🔴 Hors ligne

Pied de page des forums