Page 1 sur 2
REGEX et parsing HTML [Résolu]
Publié : ven. 06/juil./2018 20:05
par Kwai chang caine
Bonjour à tous
Je suis tombé sur un super code de "Deluxe0321" qui parsait de l'HTML avec des REGEX (Cool l'idée)
Seulement voilà, il ne parse "que" les attributs et les balises, pas le texte des balises
Les passionnés des REGEX (comment est ce possible

) sauraient il comment récupérer le texte plutôt que l'attribut des balises ?
Code : Tout sélectionner
AExpression.s = "(\S+)=["+#DQUOTE$+"']?((?:.(?!["+#DQUOTE$+"']?\s+(?:\S+)=|[>"+#DQUOTE$+"']))+.)["+#DQUOTE$+"']?"
Code : Tout sélectionner
InitNetwork()
;// html tag expression --> http://haacked.com/archive/2004/10/25/usingregularexpressionstomatchhtml.aspx
Expression.s = "</?\w+((\s+\w+(\s*=\s*(?:"+#DQUOTE$+".*?"+#DQUOTE$+"|'.*?'|[^'"+#DQUOTE$+">\s]+))?)+\s*|\s*)/?>"
;// html attribute expression --> http://stackoverflow.com/a/317081
AExpression.s = "(\S+)=["+#DQUOTE$+"']?((?:.(?!["+#DQUOTE$+"']?\s+(?:\S+)=|[>"+#DQUOTE$+"']))+.)["+#DQUOTE$+"']?"
RegEx.i = CreateRegularExpression(#PB_Any,Expression.s)
ARegEx.i = CreateRegularExpression(#PB_Any,AExpression.s)
If RegEx.i and ARegEx.i
If ReceiveHTTPFile("http://www.purebasic.fr/english/", GetHomeDirectory()+"tmp.html")
If OpenFile(0,GetHomeDirectory()+"tmp.html")
*mem = AllocateMemory(Lof(0))
If *mem
ReadData(0,*mem,Lof(0))
CloseFile(0)
EndIf
DeleteFile(GetHomeDirectory()+"tmp.html")
EndIf
Content.s = PeekS(*mem,-1,#PB_Ascii)
FreeMemory(*mem)
Debug Content.s
Dim Arr.s(0)
Dim AArr.s(0)
ArrSize.i = ExtractRegularExpression(RegEx.i,Content.s,Arr())
If ArrSize.i
Debug "Found "+Str(ArrSize.i)+" HTML Tags:"
For i=0 To ArrSize.i - 1
ReDim AArr(0)
AArrSize.i = ExtractRegularExpression(ARegEx.i,Arr(i),AArr())
Debug Space(4) + "HTML-Tag:"
Debug Space(8) + Arr(i)
If AArrSize
Debug Space(4) + "Attributes: "
For i2 = 0 To AArrSize.i - 1
Debug Space(8) + AArr(i2)
Next
EndIf
Next
EndIf
EndIf
EndIf
Merci et bonne journée
Re: REGEX et parsing HTML
Publié : ven. 06/juil./2018 20:24
par Ar-S
Salut KCC
Tu veux procéder par regex ?
Parce qu'une petite procédure de findstring() pourrait suffire vu que les textes sont... Balisés !
En attendant, évitons de polluer l'ordi avec des fichiers temp maintenant qu'on a ReceiveHTTPMemory().
Remplace
Code : Tout sélectionner
If ReceiveHTTPFile("http://www.purebasic.fr/english/", GetHomeDirectory()+"tmp.html")
If OpenFile(0,GetHomeDirectory()+"tmp.html")
*mem = AllocateMemory(Lof(0))
If *mem
ReadData(0,*mem,Lof(0))
CloseFile(0)
EndIf
DeleteFile(GetHomeDirectory()+"tmp.html")
EndIf
Content.s = PeekS(*mem,-1,#PB_Ascii)
FreeMemory(*mem)
Debug Content.s
par
Code : Tout sélectionner
*Buffer = ReceiveHTTPMemory("http://www.purebasic.fr/english//index.php")
If *Buffer
Taille = MemorySize(*Buffer)
Content.s = PeekS(*Buffer, Taille, #PB_Ascii)
FreeMemory(*Buffer)
Debug Content.s
Re: REGEX et parsing HTML
Publié : ven. 06/juil./2018 21:19
par Kwai chang caine
Bonjour ARS
Bah disons que j'ai trouvé ce code assez performant pour sa petitesse

J'ai lu que l'on ne peut pas faire de la perfection avec les REGEX pour ce qui est du HTML, mais ce code s'en tire pas mal
Alors je me suis dit que c'était dommage que la demande initiale n'était que sur les attributs, car avec les textes il aurait été assez complet.
Maintenant c'est sûr qu'utiliser ce genre de code, c'est fatalement rendre les aficionados des REGEX indispensables

Mais comment peut on pouvoir répondre à ma question sans user 3 boites de cachets et risquer une année de dépression

Re: REGEX et parsing HTML
Publié : ven. 06/juil./2018 23:13
par Ar-S
Un ancien code de G-Rom pour extraire entre les balises.
Code : Tout sélectionner
Procedure.s ExtractFromTag(Text.s, open.s, close.s)
PosA = FindString(Text,open,1) + Len(open)
PosB = FindString(Text,close,2)
Out$ = Mid(Text,PosA,PosB-PosA)
ProcedureReturn Out$
EndProcedure
REGEX_MASK_H_1_6$ = "<h([1-6])>([^<]*)</h([1-6])>"
REGEX_MASK_STRONG$ = "<strong>([^<]*)</strong>"
REGEX_MASK_PROCEDURE$ = "Procedure([^<]*)\)"
n$ = "<h1>This is a crappy tag</hx>"
n$ + "<h1>This is a good title !</h1>"
n$ + "<h1>this bad tag is bypass the regex </hc>"
n$ + "<strong>HARD BYTE!</strong>"
n$ + "<strong>HARD BYTE! second time</strong>"
n$ + "<BadTag>DUR COMME MA BYTE!</BadTag>"
n$ + "Prcocedure Test(A.f)"
n$ + "Procedurdes Floo(A.f)"
n$ + "Procedure Floo(A.f)"
;-Extraction des titres :
exp = CreateRegularExpression(#PB_Any,REGEX_MASK_H_1_6$)
Dim Titre$(0)
TitreFound = ExtractRegularExpression(exp,n$, Titre$())
FreeRegularExpression(exp)
;-Extraction des strong :
exp = CreateRegularExpression(#PB_Any,REGEX_MASK_STRONG$)
Dim Strong$(0)
StrongFound = ExtractRegularExpression(exp,n$, Strong$())
FreeRegularExpression(exp)
;-Extraction des procedures :
exp = CreateRegularExpression(#PB_Any,REGEX_MASK_PROCEDURE$)
Dim Proc$(0)
ProcFound = ExtractRegularExpression(exp,n$, Proc$())
FreeRegularExpression(exp)
Debug "Good Title :"
For k = 0 To TitreFound-1
Debug "- "+ExtractFromTag(Titre$(k),"<h1>","</h1>")
Next
Debug "Strong & Ok :"
For k = 0 To StrongFound-1
Debug "- "+ExtractFromTag(Strong$(k),"<strong>","</strong>")
Next
Debug "Good Proce :"
For k = 0 To ProcFound-1
Debug "- "+Proc$(k)
Next
Re: REGEX et parsing HTML
Publié : ven. 06/juil./2018 23:24
par Ollivier
Code : Tout sélectionner
;**************************************************************************************************************
Procedure.S Up(C.S, M.S)
A = FindString(C, ">", FindString(C, "<" + M, 1, #PB_String_NoCase) ) + 1
ProcedureReturn Mid(Content, A, FindString(C, "</" + M, A, #PB_String_NoCase) - A)
EndProcedure
Debug Up(Content, "HEAD")
Re: REGEX et parsing HTML
Publié : ven. 06/juil./2018 23:46
par Ollivier
(
1) tolère la casse différentiée
2) tolère les espaces post-balise
3) tolère la présence de membres au sein des balises
4) tolère les caractères de balise inter-balise
5) tolère les entrelacements de balise
Norme W3C (Liens directs et version française traduite par mes soins en section Hors-Sujet)
)
Re: REGEX et parsing HTML
Publié : sam. 07/juil./2018 9:05
par Kwai chang caine
Waoouh !!!
@Ars
J'étais passé à coté de ce code et pourtant c'est pas faute de hanter les forums toute la journée

Il marche apparemment nickel, je testerais sur les pages que je dois parser
On reconnait bien la signature de notre G-Rom national

Merci beaucoup ARS
@Ollivier
Merci pour ton code mais il ne fonctionne pas
J'ai du remplacé la variable "content" par "C" si j'ai bien compris
De plus, on est obligé apparemment il ne remonte pas le bon texte, ni avec le HTML bidon de GRom, ni avec le HTML du site PB de ARS
Code : Tout sélectionner
n$ = "<h1>This is a crappy tag</hx>"
n$ + "<h1>This is a good title !</h1>"
n$ + "<h1>this bad tag is bypass the regex </hc>"
n$ + "<strong>HARD BYTE!</strong>"
n$ + "<strong>HARD BYTE! second time</strong>"
n$ + "<BadTag>DUR COMME MA BYTE!</BadTag>"
n$ + "Prcocedure Test(A.f)"
n$ + "Procedurdes Floo(A.f)"
n$ + "Procedure Floo(A.f)"
Procedure.S Up(C.S, M.S)
A = FindString(C, ">", FindString(C, "<" + M, 1, #PB_String_NoCase) ) + 1
ProcedureReturn Mid(C, A, FindString(C, "</" + M, A, #PB_String_NoCase) - A)
EndProcedure
InitNetwork()
*Buffer = ReceiveHTTPMemory("http://www.purebasic.fr/english//index.php")
If *Buffer
Taille = MemorySize(*Buffer)
Content.s = PeekS(*Buffer, Taille, #PB_Ascii)
FreeMemory(*Buffer)
;Debug Up(Content$, "")
EndIf
Debug Up(Content, "HEAD")
Quoi qu'il en soit, merci à vous deux !!!!

Re: REGEX et parsing HTML [Résolu]
Publié : sam. 07/juil./2018 10:12
par Ollivier
@Ollivier
Mercipour ton code maisil ne fonctionnepas
J'ai du remplacéla variable"content" par "C" si j'ai biencompris
C'est une bonne réponse. Kcc n'est pas content. Car, malgré ses soins délicats, la défroqueuse de page HTML ne fonctionne pas.
Re: REGEX et parsing HTML [Résolu]
Publié : sam. 07/juil./2018 10:22
par Marc56
Si ta page ne contient que du HTML de base, il suffit de prendre ce qui est entre > et <
Code : Tout sélectionner
If CreateRegularExpression(0, "\>(.+)\<")
If ExamineRegularExpression(0, "<MaBalise>Je cherche à récupérer ce texte</MaBalise>")
While NextRegularExpressionMatch(0)
Debug RegularExpressionGroup(0, 1)
Wend
EndIf
Else
Debug RegularExpressionError()
EndIf
Mais, maintenant, la plupart des pages HTML étant infestées de css, javascript, flash, truc pour le bling-bling et autres s.....peries pour imposer de la pub, ça devient quasi impossible de faire un filtre efficace.
Cette regex va par exemple exclure le javascript, donc le texte qui a été généré par lui selon l'action utilisateur.
Si ta page est une page statique ou générée par le serveur (ex: PHP ou CGI), alors le code est filtrable puisque le navigateur ne reçoit que le produit du script.
Si c'est juste du HTML "normal" de la grande époque (c'est à dire conçu pour être lu par tout le monde et même avec un navigateur texte comme Lynx), alors donne-moi une url et le te fais la RegEx qui ira bien.
Re: REGEX et parsing HTML [Résolu]
Publié : sam. 07/juil./2018 11:16
par Kwai chang caine
Merci beaucoup Marc
Ton code marche déjà pas mal, mais tu dois t'en douter il en remonte plus que prévu
La bonne nouvelle, c'est que c'est du "vebe" de chez "vebe" pas de pubs à la con, juste du JS pour faire joli, mais vraiment limité au max, c'est pour le boulot, et on rigole pas au boulot
Donc le problème c'est que ce sont des pages intranets, inaccessibles de l’extérieur, mais surtout blindées d'informations confidentielles de clients ou de ma boite
C'est pas aussi simple que après les ">" et avant les "<" car il y a des tableaux ...
Par contre, je peux te donner un extrait dans lesquels je cherche à retourner le texte
29276985
45 AVENUE ROSA PARKS
A
RDC
69009 LYON
000000000000
11111111
En service
BOUDOU JEAN-CLAUDE
Code : Tout sélectionner
[code]<tbody>
<tr class="odd">
<td style="width: 110px;"><a id="lien" class="buttonDoAfficher" href="/Portail/appmanager/portail/bureau?_nfpb=true&_windowLabel=lFiche_2&_pageLabel=_page_rechercherUnPoint&wsrp-urlType=blockingAction&wsrp-secureURL=true&wsrp-url=&wsrp-requiresRewrite=&wsrp-navigationalValues=&wsrp-navigationalState=eJyLL07OO0i1Pc-JT0rMYYNQtgBZ6Cf8&wsrp-interactionState=wlplFiche_2_id%3E29276985%26wlplFiche_2_action%3Dtrouver%26wlplFiche_2_criteresRecherche%3DcriteresRechercheValue&wsrp-mode=&wsrp-windowState=&">29276985</a></td>
<td style="max-width: 180px;">45 AVENUE ROSA PARKS</td>
<td style="width: 58px;">A</td>
<td style="width: 75px;">RDC</td>
<td style="width: 58px;"></td>
<td style="width: 58px;">69009 LYON</td>
<td style="width: 95px;" class="NumSerie">000000000000</td>
<td style="width: 58px;" class="type">11111111</td>
<td style="width: 65px;" class="etat">En service</td>
<td style="width: 110px;" class="nomClient">BOUDOU JEAN-CLAUDE</td></tr>
<tr class="even">
Le même bloc se reproduit et fini par </tbody> à la toute fin
Re: REGEX et parsing HTML [Résolu]
Publié : sam. 07/juil./2018 17:23
par Marc56
À l'arrache (et pour une seule ligne pour l'instant) le reste demain.
Mets ton fichier html dans data.txt
La RegEx est moche mais c'est ̶ ̶p̶a̶r̶c̶e̶ ̶q̶u̶e̶ ̶j̶'̶a̶i̶ ̶l̶a̶ ̶f̶l̶e̶m̶m̶e̶ ̶d̶e̶ ̶r̶o̶u̶v̶r̶i̶r̶ ̶l̶a̶ ̶d̶o̶c̶ ̶p̶a̶r̶c̶e̶ ̶q̶u̶'̶i̶l̶ ̶f̶a̶i̶t̶ ̶t̶r̶o̶p̶ ̶c̶h̶a̶u̶d̶ pour la compréhension
Seul le début est différent, ensuite je copie/colle .+>(.*)</td> 9 fois
Code : Tout sélectionner
EnableExplicit
; Données à trouver
;
; 29276985
; 45 AVENUE ROSA PARKS
; A
; RDC
;
; 69009 LYON
; 000000000000
; 11111111
; En service
; BOUDOU JEAN-CLAUDE
Enumeration
#hFile
#RegEx
EndEnumeration
; --- Load datafile
If Not ReadFile(#hFile, "Datas.txt")
MessageRequester("Error", "No data file")
End
EndIf
Define Txt$
While Not Eof(#hFile)
Txt$ = ReadString(#hFile, #PB_File_IgnoreEOL)
Wend
CloseFile(#hFile)
; ---
Define RegEx$ = ~"&\">(.+)</a></td>.+>(.*)</td>.+>(.*)</td>.+>(.*)</td>.+>(.*)</td>.+>(.*)</td>.+>(.*)</td>.+>(.*)</td>.+>(.*)</td>.+>(.*)</td>"
If CreateRegularExpression(#RegEx, RegEx$, #PB_RegularExpression_DotAll)
If ExamineRegularExpression(#RegEx, Txt$)
Define Nb_Cols = CountRegularExpressionGroups(#RegEx)
Define i.a
While NextRegularExpressionMatch(#RegEx)
For i = 1 To 10
Debug "" + RSet(Str(i), 2, " ") + ": " + RegularExpressionGroup(#RegEx, i)
Next
Wend
EndIf
Else
Debug RegularExpressionError()
EndIf
End
Code : Tout sélectionner
1: 29276985
2: 45 AVENUE ROSA PARKS
3: A
4: RDC
5:
6: 69009 LYON
7: 000000000000
8: 11111111
9: En service
10: BOUDOU JEAN-CLAUDE
Ça fonctionne, à condition qu'aucun champ ne contienne de < > auquel cas, il faut isoler un peu plus en augmentant les caractères devant et derrière chaque group ()
Le group () est répété 10 fois pour qu'il sorte quelque-chose même si le champs est vide.

Re: REGEX et parsing HTML [Résolu]
Publié : sam. 07/juil./2018 17:34
par Marc56
Kwai chang caine a écrit :Le même bloc se reproduit et fini par </tbody> à la toute fin
Après, soit on fait une regex plus compliquée, soit on bouche en faisant une nouvelle chaine à chaque <tbody></tbody> ou <tr></tr>
(c'est sans doute le plus simple)
Re: REGEX et parsing HTML [Résolu]
Publié : sam. 07/juil./2018 17:37
par Marc56
Et pour entrer les données dans un fichier CSV ou une base SQL, tu insère les commandes SQL ou code dans la boucle
Code : Tout sélectionner
For i = 1 To 10
Debug "" + RSet(Str(i), 2, " ") + ": " + RegularExpressionGroup(#RegEx, i)
Next
Re: REGEX et parsing HTML [Résolu]
Publié : sam. 07/juil./2018 18:16
par Kwai chang caine
Merci beaucoup Marc56
Mais je pensais pas que ce serait si compliqué à faire
Etant donné que le précédent code marchait pas trop mal pour les attributs et les balises, je pensais qu'il fallait juste modifier un peu le REGEX des attributs pour obtenir les textes
J'ai lancé ton code et les style et class remontent aussi
Code : Tout sélectionner
<td style="width: 110px;" class="nom">Kiki la houpette</td></tr>
<tr class="even">
Bon te casse pas plus la tête, si c'est si compliqué, je passerais par le parsing traditionnel ou j'utiliserais le code de Grom
Je voudrais pas que tu surchauffe
Quoi qu'il en soit, je te remercie déjà mille fois d'avoir pris le temps de m'aider

Re: REGEX et parsing HTML [Résolu]
Publié : dim. 08/juil./2018 10:16
par Ollivier
Kcc,
quand tu rentres dans une cabine d'essayage, on enlève les pantalons au fur et à mesure, on n'accumule pas les pantalons les uns sur les autres, sinon, au bout de 3 pantalons, on ne peut plus plier un genou sans s'exploser les grelots...