Vous n'êtes pas identifié(e).
Salut,
j'utilise la classe simple_html_dom.php depuis un moment pour faire du scrapping, mais aujourd'hui je rencontre une limite. Je suis presque certain qu'il y a une solution
En récupérant le dom de n'importe quelle page, on peut par exemple extraire la valeur de tous les H2 ainsi
Jusque là très bien, mais supposez que je veuille garder le dom original tel quel, à la différence que je veux remplacer toutes les valeurs des balises h2 par "Hello World".
D'après ce que j'ai lu il suffit de faire ça
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.
Normalement cela doit être tout à fait possible de faire ça avec cette classe, c'est certainement moi qui l'utilise mal. Est-ce que quelqu'un peu éclairer ma lanterne ?
Merci d'avance pour vos contribs
🔴 Hors ligne
je pense que ton $h2 est une copie c'est pour cela que ça ne modifie pas.
je n'ai pas d'environnement PHP sous la main mais tu peux commencer par tenter de passer $h2 par référence en l'appelant &$h2 : http://php.net/manual/fr/language.references.pass.php
Mais vu que tu modifie le dom dans ta boucle foreach j'ai un doute que cela fonctionne comme cela...
Bon courage, je regarderai ça plus en détail demain si tu es toujours coincé
🔴 Hors ligne
Si la solution du dessus ne marche pas, tu peux faire :
CeKwa ?
🔴 Hors ligne
Si la solution du dessus ne marche pas, tu peux faire :
include('simple_html_dom.php');
$html = new simple_html_dom();
$html = file_get_html('http://www.site-web.com');
foreach ($html->find('h2') as $key => $h2) {
$h2->plaintext = 'hello world';
$html->find('h2', $key)->innertext = 'foo';
}
Top ! ben oui, tu modifies direct l'objet, j'essaie de suite
Merci Soul
🔴 Hors ligne
Merci Soul, ça marche très bien comme àa en modifiant l'objet avec la bonne clé. C'est la bonne piste pour moi.
Pour l'instant je me heurte à des problèmes un peu plus chauds, par exemple quand les tags incluent d'autres tags.
Si j'ai ça par exemple...
<p>Salut les <a href="file.html">amis</a></p>
Je dois réussir à remplacer par
<p>Coucou les <a href="file.html">potes</a>
Le tout sans savoir à l'avance si je vais manipuler des tag <li>,<p>,<h2>,<div>, etc.
je dois réussir à modifier
🔴 Hors ligne
avec ce que tu as deja tu detecte les sequences, tu prépare tes spins a coté, en regardant ce qui match entre tes sequences et ton dico, puis après c'est la toute la question.
des str replaces a partir des sequences de base comme facteur de detection ? assez sécurisé quand même, genre pas sur un mot ou deux, mais un groupe de sequence spinnée, du même element, interpreté et prete a être remplacante de la sequence de base.
Sinon recréer un nouveau dom et utilisant ce que tu ne va pas modifier de l'original, la lecture pour cela suffit, puis a la volée les partie que tu souhaite spinner tu les traite.
Je ferai comme ca perso je pense.
⌕ Comment Ranker ?
▶ Nouveauté : Ninja Web Pro Pack copies limitées !
▶ Ebook : Ninjalinking 2022 (-25% : labo25e)
▶ Conseils stratégiques ou techniques ? ( Skype : jaffaarbh )
🟢 En ligne
Jaffaar... j'ai capté quetchi !
Mais qu'est ce qui te fait croire que je veux faire du content spinning ?
Oh trois fois rien , on en parle sur skype
⌕ Comment Ranker ?
▶ Nouveauté : Ninja Web Pro Pack copies limitées !
▶ Ebook : Ninjalinking 2022 (-25% : labo25e)
▶ Conseils stratégiques ou techniques ? ( Skype : jaffaarbh )
🟢 En ligne
Ça ressemble à quoi ta chaîne d'entrée ?
Si ta "Salut les" => "Coucou les", tu fais un str_replace(">Salut les<", ">Coucou les<") mais je suis pas sur de comprendre ce que tu veux.
CeKwa ?
🔴 Hors ligne
Pour gérer le problème des tags, il faudrait que tu fasses des replace avec des regex, j'aime pas trop utiliser ces conneries mais bon dans l'idée si tu fais un replace de "Salut{regex}les{regex}potes"
par "Coucou{regex}les{regex}amis" avec une regex qui tolère les espaces, virgules et tag <.*> etc...
Je ne sais pas si ça répond à ta question pour le coup. Mais bon ça nécessiterai plutôt de traiter ta page en mode chaîne de caractère plutôt que comme du dom.
🔴 Hors ligne
Merci pour vos réponses, je clarifie un peu le besoin
je récupère un dom complet d'une page web quelconque. J'ai besoin de spiner le contenu (j'ai déjà un dico interne), tout en gardant le dom intact, sauf que le spin peut potentiellement casser mon dom, voilà un exemple
supposons que dans un morceau du dom j'ai <a href="referencement.html">référencement</a> et que mon spin effectue un remplacement du mot "référencement" par "SEO", je me retrouve avec <a href="SEO.html">SEO</a> ce qui ne va pas du tout pour moi.
C'est pour ça que plutôt que de travailler sur le html comme une chaine de caractère j'envisage de manipuler l'objet dom
🔴 Hors ligne
Je te propose ce que j'aurais fait instinctivement, ce n'est peut être pas la solution la plus simple ni celle qui pompe le moins de mémoire.
<a href="referencement.html">référencement</a>
je fais une regex qui prend ce qu'il y a entre les balises et y compris "<" et ">", je stock dans un tableau, par ex:
tab[0] = "<a href="referencement.html">";
tab[1] = "</a>";
Et je fais un str_replace($tab[0], "%chaine0%", $source);
...
les termes tels que %chaine0%, %chaine1% ne sont pas dans ton dico donc ils ne seront pas touchés.
Puis une fois que ton contenu est spinné, tu fais ré apparaître tes liens intact.
Je suis à côté de la plaque ça se trouve lol
Aussi, je stockerais chaque type de balise (p, div, ...) dans un tableau puis foreach et si on tombe sur une balise <a href on fait ceci... sinon si on tombe sur ...
Dernière modification par Woods (2016-01-28 11:24:31)
🔴 Hors ligne
tu codes maintenant woods ?
⌕ Comment Ranker ?
▶ Nouveauté : Ninja Web Pro Pack copies limitées !
▶ Ebook : Ninjalinking 2022 (-25% : labo25e)
▶ Conseils stratégiques ou techniques ? ( Skype : jaffaarbh )
🟢 En ligne
tu codes maintenant woods ?
J'ai toujours codé Jaff , juste que c'est pour des besoins spécifiques, jamais de gros projets.
Rarement lisible et compréhensible mais le principal c'est que j'arrive à combler mon besoin lol
🔴 Hors ligne
content de l'apprendre
⌕ Comment Ranker ?
▶ Nouveauté : Ninja Web Pro Pack copies limitées !
▶ Ebook : Ninjalinking 2022 (-25% : labo25e)
▶ Conseils stratégiques ou techniques ? ( Skype : jaffaarbh )
🟢 En ligne
Après quelques galères voici un code qui fonctionne pour évoluer dans l'objet dom et modifier les valeurs ou attributs des éléments à la volée.
J'ai ajouté des flags "[protected] $var[/protected]" dans le code pour m'assurer que j'isole bien les éléments indépendamment des autres, pour pouvoir aussi faire des modif sur les éléments "parent" sans casser les modif éventuellement effectuées sur des éléments "enfant". En fonction de ce que vous voulez faire il suffit de manipuler $var
function parse($html){
foreach($html->find('*') as $key => $tag){
$array = $tag->children(-1);
if ($array){
parse($tag);
if(preg_match('#\[\/protected\]#',$tag->innertext) && $tag->tag!='img'){
$string = str_replace('[/protected]','[/protected]***',strip_tags($tag->innertext));
$tab = explode('***',$string);
foreach($tab as $match){
$match = preg_replace('#\[protected\](.*)\[\/protected\]#','',$match);
if(preg_match('#[a-z]{2,}#U',$match)){
$new_val = '[protected]'.$match.'[/protected]';
$tag->innertext = str_replace($match,$new_val,$tag->innertext);
}
}
}
else {
if($tag->tag!='img' && preg_match('#[a-z]{2,}#i',$tag->plaintext))
$tag->innertext = '[protected]'.$tag->innertext.'[/protected]';
}
}
else {
if($tag->tag!='img' && preg_match('#[a-z]{2,}#i',$tag->plaintext))
$tag->innertext = '[protected]'.$tag->innertext.'[/protected]';
}
}
}
N'hésitez pas si vous voyez des erreurs dans le code, je l'ai utilisé à plusieurs reprises sans erreurs pour le moment
🔴 Hors ligne
echo $doc->saveHTML();
Sinon comme ça
bon apres le str_replace tu mets ce que tu veux a la place biensur
🔴 Hors ligne
<?php
$doc = new DOMDocument;
@$doc->loadHTMLFile('http://www.lightonseo.com/');
$xpath = new DOMXPath($doc);
$nodes = $xpath->query('//text()');
foreach ($nodes as $node) {
$node->nodeValue = str_replace("SEO", "Bigorno", $node->nodeValue);
}echo $doc->saveHTML();
Sinon comme ça
bon apres le str_replace tu mets ce que tu veux a la place biensur
Alors le code que j'ai posté marche très bien, par contre le tiens à l'air bien frais
Je vais regarder ça, mais elle fait quoi exactement la methode query('//text()') ? J'ai pas encore maté la doc
J'ai jamais utilisé DOMDocument pour l'instant, mais ce qui est rassurant avec c'est que c'est maintenu et dans la doc php, contrairement à la classe simple_html_dom (qui fonctionne aujourd'hui) mais qui n'est plus du tout maintenue
🔴 Hors ligne
texte ba ça selectionne le texte uniquement entre les balises.
d'ailleur le code prendra le javascript
la ça ne prendra uniquement que le contenu du body.
Ce qui est cool et rapide avec xpath en plus c'est que si tu veut allez vite :
1/Tu va sur ton site (example le tien)
2/ clic droit inspecté élément
3/ Dans le code source tu fait clique droit sur la zone (genre <p></p>) qui t’intéresse
4/ Copy -> Copy Xpath (//*[@id="post-1227"]/div[2]/p)
5/ Tu modifie ton bout de code : $nodes = $xpath->query('//*[@id="post-1227"]/div[2]/p//text()');
et voila en 3 clique tu peu ciblé une zone précises sachant que le * reste ton meilleur amis : tu peu faire : $nodes = $xpath->query('//*[@id="post-*"]/div[2]/p//text()');
donc prendre uniquement les Posts de la page
🔴 Hors ligne
texte ba ça selectionne le texte uniquement entre les balises.
d'ailleur le code prendra le javascript
$nodes = $xpath->query('/html/body//text()');
la ça ne prendra uniquement que le contenu du body.
Ce qui est cool et rapide avec xpath en plus c'est que si tu veut allez vite :
1/Tu va sur ton site (example le tien)
2/ clic droit inspecté élément
3/ Dans le code source tu fait clique droit sur la zone (genre <p></p>) qui t’intéresse
4/ Copy -> Copy Xpath (//*[@id="post-1227"]/div[2]/p)
5/ Tu modifie ton bout de code : $nodes = $xpath->query('//*[@id="post-1227"]/div[2]/p//text()');et voila en 3 clique tu peu ciblé une zone précises sachant que le * reste ton meilleur amis : tu peu faire : $nodes = $xpath->query('//*[@id="post-*"]/div[2]/p//text()');
donc prendre uniquement les Posts de la page
Oui mais non
Si tu lis bien le thread, le besoin était d'explorer tous les noeuds sans connaître à l'avance le site sur lequel tu opères. Quand il s'agit d'un site que tu connais pas de souci.
Le problème avec ça :
est que je vais récupérer un full text qui dans mon cas est inutile, j'avais besoin de préserver tout le code html de la page. La solution devait pouvoir boucler sur tous les noeuds du dom et être efficace même sur les cas particuliers. Je te donne deux exemples
Si je demande a un parser de me filer les plaintext de toutes les balises html, il va me filer "mon super test" deux foix : 1 fois pour <strong> et une fois pour <a>. Or dans l'exemple ci-dessus j'ai besoin qu'il ignore le strong. Voici un autre cas plus chiant.
Si je veux spinner le contenu de la balise p, j'ai du découper et spinner les zones qui ne contiennent pas de tag enfants :
*** Bonjour à tous
*** Nous pourrions
*** Une sortie
Ensuite j'ai du spinner le contenu des tags enfants avec le même besoin de vérifier si eux mêmes n'avaient pas de tag enfants. Pour les balises strong par exemple
*** la meteo est
*** depuis quelques jours
*** envisager
Je voulais aussi éviter les regex, parce que c'est chiant et pour éviter des soucis à cause d'erreurs html
Le fait est que j'ai réussi à le faire avec du parsing, ç'est gourmand en mémoire mais ça marche. Bien sûr je suis ouvert à toute alternative ou méthode différente plus simple ou qui ferait gagner du temps
🔴 Hors ligne