Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

regex pour isoler le contenu d'un body

21 réponses
Avatar
SuperG2
Bonjour

Alors la, je marche sur la corde raid ... Admirez l'équilibriste ... :)

Une regex ... oui oui, ce mot barbare que j'ai lu il y a deux ans ... Ce mot
qui me faisiat pensé que ... le jour ou je le comprendrais je pourais peut
être dire que je connais un piti peu le PHP ... :p

Et bien voilà, je suis en plein dedant :)

J'utilise un logiciel CMS pour rédiger un contenu à mettre en ligne, et la
seule solution pour rendre le travail propre serait que j'arrive a récupérer
le contenu alors généré ... (Un sacré bordel lol)

Comment alors pourais je récupérer le body, son contenu et le /body pour
laisser se mourir notre pauvre doctype préconfiguré ainsi que les données du
head :p

Merci de vos avis éclairés, en attendant je vais allumer la lumière ;-)

Super G2 en mode aille ma nuque, c'est pas possible !

10 réponses

1 2 3
Avatar
Mickael Wolff

Bon, et comment faire ?
Depuis, j'avais vu ce manque, et cette fois je récupère *tout* le texte
mais vraiment *tout* et y compris celui des autres balises et en un seul
jet.
:-(


Si tu consultes l'attribut textContent de l'élément, tu récupère
effectivement tout le texte contenu dans le n½ud élément et ces enfants.


A ce que je comprends, l'idée est de réceptionner une page (sans doute
construite par une espèce de formulaire) d'en extraire que le contenu
("contenu du body") pour l'intégrer dans une partie d'une autre et à mon
idée c'est vraiment un travail à faire traiter via le DOM.

Avec un peu de chance le résultat pourra être un peu + standard ?

L'exemple donné ne passant pas au validateur :
" You have used character data somewhere it is not permitted to appear.
* putting text directly in the body of the document without wrapping
it in a container element (such as a <p>aragraph</p>)"



Oui, parce qu'il n'est pas valide. Aucune DTD n'est définie pour
commencer, ce que DOMDocument n'aime pas tellement. Mais normalement tu
peux faire en sorte que le processeur DOM soit moins tatillon. Au pire,
tu peux piéger les exceptions lancées par l'analyse et les ignorer. Au pire.

Pour récupérer le contenu texte du body, tu pourrais utiliser ça :

$bodyElmt = $dom->getElementsByTagName('body')->item(0) ;
$txtNodes = array() ;
if($bodyElmt->hasChildNodes())
foreach($body->childNodes as $baby)
if($baby->nodeType == DOMDocument::XML_TEXT_NODE)
$txtNodes[] = $baby ;

Sinon il y a une autre solution
<news:479ff308$0$12361$ que j'ai déjà détaillé.

--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org

Avatar
Olivier Miakinen
...
Comment alors pourais je récupérer le body, son contenu et le /body pour
laisser se mourir notre pauvre doctype préconfiguré ainsi que les
données du head
Une idée comme ça : comme les occurences du mot 'body' ne peuvent être

plus de 2, pourquoi ne pas commencer par un explode('body',$texte,-1) et
ainsi récupérer l'en tête et le corps ?


Non, ça ne marchera pas. Cf. l'exemple suivant :

<html>
<head>
<title>Essai de récupération du body</title>
</head>
<body>
<h1>Essai de récupération du body</h1>
<p>On veut extraire ce qui est entre body et /body.</p>
</body>
</html>

Et encore pire :

<HTML>
<HEAD>
<TITLE>Essai de récupération du body</TITLE>
</HEAD>
<BODY>
<H1>Essai de récupération du body</H1>
<P>On veut extraire ce qui est entre body et /body.</P>
</BODY>
</HTML>


Avatar
Paul
...
Comment alors pourais je récupérer le body, son contenu et le /body pour
laisser se mourir notre pauvre doctype préconfiguré ainsi que les
données du head
Une idée comme ça : comme les occurences du mot 'body' ne peuvent être

plus de 2, pourquoi ne pas commencer par un explode('body',$texte,-1) et
ainsi récupérer l'en tête et le corps ?


Non, ça ne marchera pas. Cf. l'exemple suivant :
Bien vu, mais explode('body>',$texte,-1) le fera dans tes deux cas.




Avatar
SAM

cette fois je récupère *tout* le texte
et y compris celui des autres balises et en un seul jet.


Si tu consultes l'attribut textContent de l'élément, tu récupère
effectivement tout le texte contenu dans le n½ud élément et ces enfants.


J'ai fait :

$doc = new DOMDocument();
if (!$dom = @$doc->loadHTML($texte)) {
echo "Erreur lors de l'analyse du documentn";
exit;
}
$origine = $doc->getElementsByTagName("body")->item(0);
if ($origine->hasChildNodes()) {
$txt = '';
foreach ($origine->childNodes as $nodling) {
$txt .= ' | '.$nodling->nodeValue;
}
echo $txt;
}
else echo 'Y a personne !';


L'exemple donné ne passant pas au validateur :


Oui, parce qu'il n'est pas valide. Aucune DTD n'est définie pour
commencer, ce que DOMDocument n'aime pas tellement.


Heu, je crois bien avoir fait passer l'exemple avec une DTD,
et p'têtre même avec un meta charset

Pour récupérer le contenu texte du body, tu pourrais utiliser ça :


Quoi ? Comment ? tu m'as copié ? :-)

$bodyElmt = $dom->getElementsByTagName('body')->item(0) ;
$txtNodes = array() ;
if($bodyElmt->hasChildNodes())
foreach($body->childNodes as $baby)
if($baby->nodeType == DOMDocument::XML_TEXT_NODE)


Ha Ha ! voilà qui me manquait.

$txtNodes[] = $baby ;

Sinon il y a une autre solution
<news:479ff308$0$12361$ que j'ai déjà détaillé.


Je vois que tu y sites ma source d'info et d'apprentissage.
<http://fr.php.net/manual/fr/ref.dom.php>
Ou bien je ne sais pas m'en servir, ou bien ne sais pas la lire,
mais je trouve malheureux qu'on ne nous dise pas d'entrée ce que sont :
DOMElement
DOMAttr
DOMText
DOMCharacterData
DOMEntityReference
DOMEntity
DOMProcessingInstruction
DOMComment
DOMDocument
DOMDocumentType
DOMDocumentFragment
DOMNotation

à moins que ça ne fasse appel à des notions innées ?


Je suis encore une fois effaré de la complexité du PHP, rien que pour ce
DOM on a je ne sais combien d'instructions chatouilleuses et ne suis pas
parvenu à y trouver un truc simple pour l'équivalent du innerHTML du
JavaScript par exemple.

'textContent', auquel tu fais allusion ci-haut, je le trouve au 10ieme
scroll d'écran de 'ref.dom.php'
Bon, ce serait une propriété de DOMNode
Oui? et alors ? déjà que DOMNode n'est pas dans mon petit listing
ci-dessus, comment se sert-on de ces propriétés ?

Voyons voir :
echo $doc->getElementsByTagName("body")->item(0)->textContent;
Non, ce n'est encore pas innerHTML



Ça va pas être coton d'intégrer tout ça.

Tu codes avec la doc à côté ou bien le fais-tu tout de mémoire ?


--
sm


Avatar
Olivier Miakinen

Une idée comme ça : comme les occurences du mot 'body' ne peuvent être
plus de 2, pourquoi ne pas commencer par un explode('body',$texte,-1) et
ainsi récupérer l'en tête et le corps ?


Non, ça ne marchera pas. Cf. l'exemple suivant :
Bien vu, mais explode('body>',$texte,-1) le fera dans tes deux cas.



Dans le premier cas oui, mais pas dans le second (avec les balises en
majuscules). Et il ne marchera pas non plus dans le cas suivant, dont je
crois bien qu'il est valide :

<html>
<head>
<title>Essai de récupération du &lt;body></title>
</head>
<body>
<h1>Essai de récupération du &lt;body></h1>
<p>On veut extraire ce qui est entre &lt;body> et &lt;/body>.</p>
</body>
</html>

Au fait, il ne fonctionnera pas non plus pour le code suivant, valide
HTML 4.01 Strict, mais aucune solution à base de regexp ne fonctionnera
ici, contrairement à une solution à base de DOM :

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<title>Ceci est le titre, dans le HEAD</title>
<p>Ceci est un paragraphe, dans le BODY.



Avatar
Mickael Wolff

J'ai fait :

$doc = new DOMDocument();
if (!$dom = @$doc->loadHTML($texte)) {
echo "Erreur lors de l'analyse du documentn";
exit;
}


Attention ! loadHTML ne renvoie pas la même valeur si il est utilisé
comme méthode de l'objet ou comme fonction statique
<http://fr2.php.net/manual/fr/function.dom-domdocument-load.php> :

if (! @$doc->loadHTML($texte)) {
echo "Erreur lors de l'analyse du documentn";
exit;
}

Quoi ? Comment ? tu m'as copié ? :-)


Bah, je complète :p


Je vois que tu y sites ma source d'info et d'apprentissage.
<http://fr.php.net/manual/fr/ref.dom.php>
Ou bien je ne sais pas m'en servir, ou bien ne sais pas la lire,
mais je trouve malheureux qu'on ne nous dise pas d'entrée ce que sont :


Comme dit en préambule de la documentation de l'implémentation de
l'API DOM, ils supposent que tu connaissent déjà les principes, ou que
tu ais lu la documentation normalisant DOM
<http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html>


Je suis encore une fois effaré de la complexité du PHP, rien que pour ce
DOM on a je ne sais combien d'instructions chatouilleuses et ne suis pas
parvenu à y trouver un truc simple pour l'équivalent du innerHTML du
JavaScript par exemple.


Il n'y en a pas, et heureusement. innerHTML c'est quand même la porte
ouverte à des choses bien gorets, non ? Et puis c'est pas standard. Et
puis c'est la même API en javascript.


'textContent', auquel tu fais allusion ci-haut, je le trouve au 10ieme
scroll d'écran de 'ref.dom.php'
Bon, ce serait une propriété de DOMNode
Oui? et alors ? déjà que DOMNode n'est pas dans mon petit listing
ci-dessus, comment se sert-on de ces propriétés ?


Le problème de la documentation PHP est qu'elle défini dans l'ordre
alphabétique les classes. Ce qui pour l'apprentissage n'est pas du
meilleurs goût. Regardes la documentation du W3C qui est un peu plus «
didactique ».


Voyons voir :
echo $doc->getElementsByTagName("body")->item(0)->textContent;
Non, ce n'est encore pas innerHTML


Et tu n'en auras pas. Enfin, tu peux bricoler quelque chose, j'ai déjà
fait, mais c'est un peu dégueux (créer un DOMDocumentFragment à partir
de la chaine que tu veux intégrer, faire adopter les n½uds de ce
fragment par le DOM de destination, et les placer dans l'arborescence).

Ça va pas être coton d'intégrer tout ça.


Tu n'utilisais jamais ça en javascript ?

Tu codes avec la doc à côté ou bien le fais-tu tout de mémoire ?


l'API est bien faite, au bout d'un moment ça rentre. Mais je garde
toujours une feuille à côté de moi avec ce que j'oublie systématiquement ;)

--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org

Avatar
Paul
...
Au fait, il ne fonctionnera pas non plus pour le code suivant, valide
HTML 4.01 Strict, mais aucune solution à base de regexp ne fonctionnera
ici, contrairement à une solution à base de DOM :


Voilà une analyse complète. Merci.

Avatar
SAM

Bon, finalement, si on continue ici, je n'ouvre pas de fil.

J'ai fait :

$doc = new DOMDocument();
if (!$dom = @$doc->loadHTML($texte)) {
echo "Erreur lors de l'analyse du documentn";
exit;
}


Attention ! loadHTML ne renvoie pas la même valeur si il est utilisé
comme méthode de l'objet ou comme fonction statique
<http://fr2.php.net/manual/fr/function.dom-domdocument-load.php> :


Heu ... ils parlent là de load() et non de loadHTML()
(me reste à tester leurs exemples, car, bien sûr, je n'ai rien compris)

if (! @$doc->loadHTML($texte)) {


Oui, mais je suppose que ma variable $dom ne gène pas ?
Disons que ce soit un réflexe des fois que la condition soit à
réutiliser plus loin (bien qu'ici ... certes avec 'exit' ...)

<http://fr.php.net/manual/fr/ref.dom.php>
Ou bien je ne sais pas m'en servir, ou bien ne sais pas la lire,


Comme dit en préambule de la documentation de l'implémentation de
l'API DOM, ils supposent que tu connaissent déjà les principes, ou que
tu ais lu la documentation normalisant DOM
<http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html>


Faut juste maintenant la trouver en frenchie ;-)
<http://www.yoyodesign.org/doc/w3c/dom2-core/core.html>
m'a l'air moins complet.

trouver un truc simple pour l'équivalent du innerHTML du
JavaScript par exemple.


Il n'y en a pas, et heureusement. innerHTML c'est quand même la porte
ouverte à des choses bien gorets, non ? Et puis c'est pas standard.


Oui, certes, n'empêche c'est quand même bien pratique (si on ne s'en
sert pas n'importe comment).

Ça va pas être coton d'intégrer tout ça.


Tu n'utilisais jamais ça en javascript ?


En JS c'est comparativement essstrémement simple,
on n'a pas de notions hyper chatouilleuses comme en PHP.
Au hasard :
Entity = nom de l'entité
EntityReference = nom de l'entité appelée
si ce n'est pas se compliquer la vie ?
(encore une fois j'ai rien compris, je vais relire ... peut-être)
(j'ai comme l'impression que c'est exactement la même chose, une fois
appelé, une fois introduit. Si c'est le cas pourquoi faire une différence ?)

--
sm


Avatar
SuperG2
Au fait, il ne fonctionnera pas non plus pour le code suivant, valide
HTML 4.01 Strict, mais aucune solution à base de regexp ne fonctionnera
ici, contrairement à une solution à base de DOM :


Voilà une analyse complète. Merci.


Ha bah je suis impatient d'exploiter Dom pour récupérer du contenu :)
Ravi d'avoir pu initier la discution :)

Super G2 ohoh Super le DOM :)


Avatar
Mickaël Wolff
Bonjour,

Désolé pour le temps de réponse, j'ai été loin de mon ordinateur
quelques jours.


Bon, finalement, si on continue ici, je n'ouvre pas de fil.


Ben vi, autant utiliser ce qui existe.

Heu ... ils parlent là de load() et non de loadHTML()
(me reste à tester leurs exemples, car, bien sûr, je n'ai rien compris)


Oui, bon, certes... j'avais lu rapidement. Tu conviendras que faire la
distinction d'usage entre les deux n'est pas du meilleurs goût.

Oui, mais je suppose que ma variable $dom ne gène pas ?


C'était au cas où tu essayais d'en faire quelque chose plus tard !

<http://www.yoyodesign.org/doc/w3c/dom2-core/core.html>
m'a l'air moins complet.


Oui, la référence que je t'ai donné concerne DOM3, et celle que tu
utilises concerne DOM2.

En JS c'est comparativement essstrémement simple,
on n'a pas de notions hyper chatouilleuses comme en PHP.
Au hasard :
Entity = nom de l'entité
EntityReference = nom de l'entité appelée
si ce n'est pas se compliquer la vie ?


Parce que ce n'est pas la même chose ? Entity est la classe
représentant l'entité telle que définit dans la DTD. Alors que
EntityReference définit une occurrence de l'entité dans le document.

Si tu regardes bien, EntityReference étend Node sans plus de
précision, alors que EntityReference étend Node en ajoutant des attributs.

--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org

1 2 3