Probleme en web scrapping

Bonjour à tous

et merci déjà à ceux qui se pencheront sur mon pb

J'attaque un formulaire web internet avec un code vba. Jusque là, assez classique

Cependant, quand je modifie un champ du formulaire web par assignation du texte via vba, le champ du formulaire web change, mais il n'est pas pris en considération.

            Dim nom As String
'mySh est la feuille qui détient les différents enregistrements
            nom = mySh.Cells(i, colName).Value
'ici je cherche dans le code html du formulaire web le champ prénom
            Set HTMLButtons = HTMLDoc.all("nom")
'je récupère le bon élément (c'est testé, ça fonctionne)
            Set HTMLButton = HTMLButtons(1)
'et là je renvoie au formulaire la valeur provenant d'Excel
            HTMLButton.Value = nom 
image

Ainsi, le champ "prénom" a été rempli directement par le formulaire sur internet explorer. On voit que l'étoile devant prénom est en gris

Le champ "nom" a été rempli via vba, l'étoile demeure rouge. Je ne peux alors pas valider mon forumulaire.

Comment faire pour que le champ "nom" soit aussi considéré comme une vraie entrée ? J'ai essayé en rajoutant un vbCrLf après "nom", mais cela ne fait rien.

Comme il s'agit d'un site avec autorisation, je ne peux pas partager tout le code.

Merci bcp pour vos lumières

Bonjour,

Je ne suis pas chevronné en la matière mais je me suis retrouvé confronté aux mêmes problèmes il y a quelques temps. Donc, de mémoire, je pense aux essais suivants.

Première piste à étudier (sûrement pas la bonne) : la simulation d'un clic sur le champ

Set HTMLButton = HTMLButtons(1)
HTMLButton.click
HTMLButton.Value = nom 

Seconde piste, la temporisation car les actions sur le navigateur peuvent être exécutées en même temps

Set HTMLButton = HTMLButtons(1)
HTMLButton.Value = nom
Call Temporiser 'temporisation avant votre clic/soumission

où Temporiser est une procédure d'attente à créer par ailleurs :

Sub Temporiser()
Application.wait Now + TimeValue("00:00:01")'TimeValue("00:00:01")/10 pour rendre la temporisation plus courte
End sub

Troisième piste, l'évènement onchange qui déclenche le langage javascript (utile en cas de calcul mais peut-être aussi de validation de données) et qui "simulera" dans certains cas une saisie manuelle

Set HTMLButton = HTMLButtons(1)
HTMLButton.Value = nom
HTMLButton.FireEvent ("onchange")

Par ailleurs, pour éviter toute confusion, il serait préférable de nommer autrement vos champs qui ne sont pas des boutons

Dim nom As String, prenom as string
Dim Champs
Dim ChampNom
Dim ChampPrenom
Dim BoutonConnexion

nom = mySh.Cells(i, colName).Value
'prenom = mySh.Cells(i, colName + 1).Value 'c'est une hypothèse

Set Champs = HTMLDoc.all("nom")
Set ChampNom = Champs(1)
Set ChampPrenom = Champs(2)
Set BoutonConnexion = HTMLDoc.all("Valider") 'ceci est un exemple

ChampNom.Value = nom
'ChampNom.FireEvent ("onchange") 'au cas où
ChampPrenom.Value = prenom
'ChampPrenom.FireEvent ("onchange") 'au cas où
Call Temporiser
BoutonConnexion.Submit '(ou BoutonConnexion.Click si échec) 

Sinon, un petit essai préalable ne ferait pas de mal avec

ChampNom.InnerText = nom

Bonjour 3GB

merci bcp pour tes propositions que j'ai testées, une par une et en conjonction.

Malheureusement aucune n'est pour l'instant efficace

J'ai bien aimé l'idée de fireevent, mais non!

Je suis bien sur preneur d'autres idées tout aussi subtiles

Amicalement

Bonjour,

Ah mince !

Est-ce que tu exécutes la macro au pas à pas pour voir ce qu'il se passe ? et voir si tes variables sont correctement affectées (fenêtre variables locales) ?

Est-ce que tu pourrais mettre le code en entier ? Pour anonymiser le site, tu peux faire ça :

Dim Lien$

Lien = Range("A1").value 'en considérant que la cellule A1 contienne le lien du site

...

IE.Navigate Lien

Merci

oui, oui, je travaille sur deux écrans en mode pas à pas :-)

j'ai testé chacune de tes supers idées, en revenant en arrière (définir l'instruction suivante) à chaque proposition et en comparant la fenêtre internet

Et j'attendais avec impatience que l'étoile rouge (sans aucune allusion politique), vire au gris ...

Quant au code, je suis vmt désolé, mais je ne peux pas le partager. Il y a besoin d'un login/psw pour entrer dans la fenêtre formulaire internet. D'ailleurs, cet étape fonctionne à merveille à partir de vba via des inputbox

Amicalement

Est-ce que tu as essayé aussi avec HTMLButton.innertext à la place de HTMLButton.value ?

Mais tes identifiants n'apparaissent pas dans le code ? De toute façon, ce qui m'intéresse, c'est le code après la connexion.

Déjà que je ne maitrise pas, alors sans le code, ça serait trop compliqué...

Merci 3GB

oui pas de souci, je peux mettre le code en "anonymisant" le lien et en rajoutant des explications dans le texte. Tu verras que j'ai essayé tes différentes propositions.

Amicalement

Sub addCustomers()
'--------------------------------------------------------------------------------------------------
'Section to read different parameters
'the different customers are recorded on a worksheet 
'shParameters give the information on the place for each data
'Read parameters
    Dim colName As Integer
    Dim colSurname As Integer
    Dim colInstitute As Integer
    Dim colEmail As Integer
    Dim colTag As Integer
    Dim valDate As Date
    colName = shParametres.Range("valName").Value
    colSurname = shParametres.Range("valSurname").Value
    colInstitute = shParametres.Range("valInstitut").Value
    colEmail = shParametres.Range("valEmail").Value
    colTag = shParametres.Range("valTag").Value
    valDate = shParametres.Range("valDate").Value

    Dim i As Integer
    i = shParametres.Range("startingRow").Value
    Dim mySh As Worksheet
    Set mySh = ActiveWorkbook.ActiveSheet
'--------------------------------------------------------------------------------------------------
'Initialize the internet explorer instance  
    Dim ie As InternetExplorerMedium
    Set ie = New InternetExplorerMedium
    With ie
        .Navigate myLink
        .Visible = True
    End With
    Do While ie.Busy: DoEvents:  Loop

    Dim HTMLDoc As New HTMLDocument
    Set HTMLDoc = ie.Document
'--------------------------------------------------------------------------------------------------
'Get the login/psw
'To obtain username and password
    Dim user As String
    Dim psw As String
    user = InputBox("user")
    psw = InputBox("psw")
'Fill the data
    Dim HTMLElement As MSHTML.IHTMLElement
    Set HTMLElement = HTMLDoc.all("password")
    If (HTMLElement Is Nothing) Then GoTo noPsw
    On Error GoTo noPsw
    HTMLDoc.all.UserName.Value = user
    HTMLDoc.all.Password.Value = psw

    Dim HTMLButtons As MSHTML.IHTMLElementCollection
    Set HTMLButtons = HTMLDoc.getElementsByClassName("btn-submit")
    Dim HTMLButton As MSHTML.IHTMLElement

    Set HTMLButton = HTMLButtons(0)
    HTMLButton.Click

    Application.Wait (Now() + TimeValue("00:00:03"))
'--------------------------------------------------------------------------------------------------
'Now give the different details
'read each row, if no more data exit, if customer already in the base do not add, else create a new customer
   Do While (True)
        If (mySh.Cells(i, colTag).Value = "") Then
'Case to click
            Set HTMLButtons = HTMLDoc.getElementsByName("new_user")
            Set HTMLButton = HTMLButtons(1)
            HTMLButton.Click
'--------------------------------------------------------------------------------------------------
'C'est à partir de là que je teste tes différentes possibilités ... mais que l'étoile rouge demeure :-)
'Fore name
            Dim prenom As String
            prenom = mySh.Cells(i, colSurname).Value
            Set HTMLButtons = HTMLDoc.all("prenom")
            Set HTMLButton = HTMLButtons(1)
            HTMLButton.Value = prenom & vbCrLf
            HTMLButton.Click
            HTMLButton.FireEvent ("onchange")
'Name
            Dim nom As String
            nom = mySh.Cells(i, colName).Value
            Set HTMLButtons = HTMLDoc.all("nom")
            Set HTMLButton = HTMLButtons(1)
            HTMLButton.Click
            HTMLButton.innerText = nom
            HTMLButton.Click
'            HTMLButton.Value = nom
'            Application.Wait Now + TimeValue("00:00:01")
            HTMLButton.FireEvent ("onchange")
'institut
            Dim organisme As String
            organisme = mySh.Cells(i, colInstitute).Value
            Set HTMLButtons = HTMLDoc.all("organisme")
            Set HTMLButton = HTMLButtons(1)
            HTMLButton.Click
            HTMLButton.Value = organisme
            HTMLButton.Click
'Email
            Dim email As String
            email = mySh.Cells(i, colEmail).Value
            Set HTMLButtons = HTMLDoc.all("mail")
            Set HTMLButton = HTMLButtons(1)
            HTMLButton.Value = email
'Date
            Dim enddate As Date
            enddate = valDate
            Set HTMLButtons = HTMLDoc.all("end_date")
            Set HTMLButton = HTMLButtons(1)
            HTMLButton.Value = enddate
'soumission 
            Set HTMLButtons = HTMLDoc.getElementsByClassName("btn btn-primary btn-block ng-binding ng-scope")
            Set HTMLButton = HTMLButtons(0)
            HTMLButton.Click
            ie.Navigate monLien
            mySh.Cells(i, colTag).Value = "ok"
        End If
        i = i + 1
        If (mySh.Cells(i, 1).Value = "") Then
            Exit Do
        End If
   Loop

    Set HTMLButton = Nothing
    Set HTMLButtons = Nothing
    Set ie = Nothing
End Sub

Re Jeb,

Bon j'ai apporté de minimes modifications, qui malheureusement n'auront probablement pas l'effet escompté. Mais c'est ce que j'aurais fait naturellement.

Sub addCustomers()

    Dim colName As Integer
    Dim colSurname As Integer
    Dim colInstitute As Integer
    Dim colEmail As Integer
    Dim colTag As Integer
    Dim valDate As Date

    colName = shParametres.Range("valName").Value
    colSurname = shParametres.Range("valSurname").Value
    colInstitute = shParametres.Range("valInstitut").Value
    colEmail = shParametres.Range("valEmail").Value
    colTag = shParametres.Range("valTag").Value
    valDate = shParametres.Range("valDate").Value

    Dim i As Integer
    i = shParametres.Range("startingRow").Value
    Dim mySh As Worksheet
    Set mySh = ActiveWorkbook.ActiveSheet
'--------------------------------------------------------------------------------------------------
'Initialize the internet explorer instance  
    Dim ie As InternetExplorerMedium
    Set ie = New InternetExplorerMedium
    With ie
        .Navigate myLink
        .Visible = True
    End With
    Do While ie.Busy: DoEvents:  Loop

    Dim HTMLDoc As New HTMLDocument
    Set HTMLDoc = ie.Document
'--------------------------------------------------------------------------------------------------
'Get the login/psw
'To obtain username and password

    Dim user As String
    Dim psw As String

    user = InputBox("user")
    psw = InputBox("psw")

'Fill the data
    Dim HTMLElement As MSHTML.IHTMLElement
    Set HTMLElement = HTMLDoc.all("password")
    If (HTMLElement Is Nothing) Then GoTo noPsw
    On Error GoTo noPsw
    HTMLDoc.all.UserName.Value = user
    HTMLDoc.all.Password.Value = psw

    Dim HTMLButtons As MSHTML.IHTMLElementCollection
    Set HTMLButtons = HTMLDoc.getElementsByClassName("btn-submit")
    Dim HTMLButton As MSHTML.IHTMLElement

    Set HTMLButton = HTMLButtons(0)
    HTMLButton.Click

    Do While ie.Busy: DoEvents:  Loop
    Application.Wait (Now() + TimeValue("00:00:03"))
    'Set HTMLDoc = ie.Document
'--------------------------------------------------------------------------------------------------
'Now give the different details
'read each row, if no more data exit, if customer already in the base do not add, else create a new customer
   Do While (True)
        If (mySh.Cells(i, colTag).Value = "") Then
'Case to click
            Set HTMLButtons = HTMLDoc.getElementsByName("new_user")
            Set HTMLButton = HTMLButtons(1)
            HTMLButton.Click
'--------------------------------------------------------------------------------------------------
'C'est à partir de là que je teste tes différentes possibilités ... mais que l'étoile rouge demeure :-)
'Fore name
            Dim prenom As String
            prenom = mySh.Cells(i, colSurname).Value
            Set HTMLButtons = HTMLDoc.all("prenom")
            Set HTMLButton = HTMLButtons(1)
            HTMLButton.Value = prenom
            HTMLButton.FireEvent ("onchange")
'Name
            Dim nom As String
            nom = mySh.Cells(i, colName).Value
            Set HTMLButtons = HTMLDoc.all("nom")
            Set HTMLButton = HTMLButtons(1)
            HTMLButton.Value = nom
            HTMLButton.FireEvent ("onchange")
'institut
            Dim organisme As String
            organisme = mySh.Cells(i, colInstitute).Value
            Set HTMLButtons = HTMLDoc.all("organisme")
            Set HTMLButton = HTMLButtons(1)
            HTMLButton.Value = organisme
            HTMLButton.FireEvent ("onchange")
'Email
            Dim email As String
            email = mySh.Cells(i, colEmail).Value
            Set HTMLButtons = HTMLDoc.all("mail")
            Set HTMLButton = HTMLButtons(1)
            HTMLButton.Value = email
            HTMLButton.FireEvent ("onchange")
'Date
            Dim enddate As Date
            enddate = valDate
            Set HTMLButtons = HTMLDoc.all("end_date")
            Set HTMLButton = HTMLButtons(1)
            HTMLButton.Value = enddate
            HTMLButton.FireEvent ("onchange")

'tempo avant validation

            Application.Wait Now + TimeValue("00:00:01")

'soumission 
            Set HTMLButtons = HTMLDoc.getElementsByClassName("btn btn-primary btn-block ng-binding ng-scope")
            Set HTMLButton = HTMLButtons(0)
            HTMLButton.Click 'HTMLButton.Submit à tester ?

            ie.Navigate monLien
            mySh.Cells(i, colTag).Value = "ok"
        End If
        i = i + 1
        If (mySh.Cells(i, 1).Value = "") Then
            Exit Do
        End If
   Loop

    Set HTMLButton = Nothing
    Set HTMLButtons = Nothing
    Set ie = Nothing
End Sub

Il y a toujours l'option d'essayer avec les sendkeys, c'est-à-dire en simulant les actions du clavier. De mémoire, c'est pas l'idéal. Le mieux serait de se plonger dans les variables et regarder tous les attributs de l'élément HTMLButton (notamment quand il agit sur le nom) pour voir ce qui pourrait bloquer.

Désolé ne pas pouvoir faire davantage (j'espérais que ça marcherait) mais c'est déjà dur en testant soi-même alors sans essayer, c'est compliqué.

Bonne soirée,

Eventuellement essayer d'ajouter des petits sleep (fonction kernel32) après les firevent car je crois qu'ils mettent en sommeil l'application (VBA) et permettent de pallier les éventuels problèmes de synchronicité. Car les instructions sont pas forcément exécutées dans l'ordre établi dans le code.

Bonjour 3GB

merci pour tous tes efforts jusqu'à tard dans la nuit

Je vais continuer à chercher, et si je trouve une solution, je la posterai ici

Amicalement

Jeb

Rechercher des sujets similaires à "probleme web scrapping"