Avatar billede punnishment Nybegynder
16. januar 2006 - 00:48 Der er 18 kommentarer og
1 løsning

Udfyld og submit formular og hent HTML

Jeg sidder med et problem lige for tiden. Jeg har brug for at loade en hjemmeside frem i VB, udfylde en formular (Det kunne både være en checkbox, select-boks eller noget helt tredje.), submitte formularen og returnere HTML koden fra den pågældende side.

Normalt henter jeg HTML koder fra hjemmesider vha. Inet, men jeg tror ikke det er muligt at submitte en formular.

Jeg kan forestille mig at man bliver nød til at bruge Microsoft Internet Controls (Web Browser). Det skal man bruge til at loade siden frem, og derefter udfylde den pågældende formular og til sidst submitte. Når den side formularen henviser til, er loaded, vil jeg gerne have den til at returnere sidens htmlkode.

Hvis alt dette er muligt, vil jeg meget gerne se nogle kodeeksempler på ovenstående (udfylde formular, submitte formular og hente html kode fra WebBrowser).

Fra tidligere arbejde med WebBrowser har jeg oplevet nogle problemer, som jeg har listet her under. Har i nogle bud på hvordan de kan løses?
- En formular kan sagtens befinde sig i en "frame"-strutur. Hvordan kommer man udenom dette problem?
- Nogle sider har JavaScript fejl, både pga. dårlig kodning men også pga. browser-tilpasnings problemer. Hvordan "ignoreres" JS-fejl?
Avatar billede thomaxz Nybegynder
16. januar 2006 - 08:10 #1
Hvis jeg skulle lave sådan, noget vil jeg fortrække winsocket, men der skal man så kennde http protokolen.



- En formular kan sagtens befinde sig i en "frame"-strutur. Hvordan kommer man udenom dette problem?

Den eneste måde, må vil være at parse koden, og finde ud af på hvilken af frame siderne, formen, ligger og henter den side ned.

- Nogle sider har JavaScript fejl, både pga. dårlig kodning men også pga. browser-tilpasnings problemer. Hvordan "ignoreres" JS-fejl?

med winsocket, har du ikke den problem.
Avatar billede punnishment Nybegynder
16. januar 2006 - 22:06 #2
Kan du give mig nogle kodeeksempler med winsock. Nu er det ikke fordi jeg har helt vildt meget styr på winsock, men så vidt jeg husker, så går den kun ind og henter HTML koden fra en given server ?

Hvordan loader jeg en side, bearbejder den, submitter og henter HTML? (Nogle meget små kodeeksempler ville være meget dejligt)
Avatar billede olebole Juniormester
17. januar 2006 - 00:40 #3
<ole>

Du kan også bruge wininet ... skriv dette i et modul:

Option Explicit

Private Declare Function InternetOpen Lib "wininet.dll" Alias "InternetOpenA" (ByVal lpszCallerName As String, ByVal dwAccessType As Long, ByVal lpszProxyName As String, ByVal lpszProxyBypass As String, ByVal dwFlags As Long) As Long
Private Declare Function InternetConnect Lib "wininet.dll" Alias "InternetConnectA" (ByVal hInternetSession As Long, ByVal lpszServerName As String, ByVal nProxyPort As Integer, ByVal lpszUsername As String, ByVal lpszPassword As String, ByVal dwService As Long, ByVal dwFlags As Long, ByVal dwContext As Long) As Long
Private Declare Function InternetReadFile Lib "wininet.dll" (ByVal hFile As Long, ByVal sBuffer As String, ByVal lNumBytesToRead As Long, lNumberOfBytesRead As Long) As Integer
Private Declare Function HttpOpenRequest Lib "wininet.dll" Alias "HttpOpenRequestA" (ByVal hInternetSession As Long, ByVal lpszVerb As String, ByVal lpszObjectName As String, ByVal lpszVersion As String, ByVal lpszReferer As String, ByVal lpszAcceptTypes As Long, ByVal dwFlags As Long, ByVal dwContext As Long) As Long
Private Declare Function HttpSendRequest Lib "wininet.dll" Alias "HttpSendRequestA" (ByVal hHttpRequest As Long, ByVal sHeaders As String, ByVal lHeadersLength As Long, ByVal sOptional As String, ByVal lOptionalLength As Long) As Boolean
Private Declare Function InternetCloseHandle Lib "wininet.dll" (ByVal hInternetHandle As Long) As Boolean
Private Declare Function HttpAddRequestHeaders Lib "wininet.dll" Alias "HttpAddRequestHeadersA" (ByVal hHttpRequest As Long, ByVal sHeaders As String, ByVal lHeadersLength As Long, ByVal lModifiers As Long) As Integer

Private Const INTERNET_OPEN_TYPE_PRECONFIG As Long = 0
Private Const INTERNET_SERVICE_HTTP        As Long = 3
Private Const INTERNET_DEFAULT_HTTP_PORT  As Long = 80
Private Const INTERNET_FLAG_RELOAD        As Long = &H80000000
Private Const HTTP_ADDREQ_FLAG_ADD        As Long = &H20000000
Private Const HTTP_ADDREQ_FLAG_REPLACE    As Long = &H80000000
Private Const HTTP_USER_AGENT              As String = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"

Public Function POSTForm(ByVal strServer As String, _
                        ByVal strScript As String, _
                        ByVal strPost As String) As String
Dim blnLoop          As Boolean
Dim intFree          As Integer
Dim strRead          As String * 2048
Dim strHeader        As String
Dim strResult        As String
Dim lngOfRead        As Long
Dim strBoundary      As String
Dim hInternetOpen    As Long
Dim hInternetConnect As Long
Dim hHttpOpenRequest As Long

  hInternetOpen = InternetOpen(HTTP_USER_AGENT, INTERNET_OPEN_TYPE_PRECONFIG, vbNullString, vbNullString, 0&)
  If Not hInternetOpen = 0 Then
    hInternetConnect = InternetConnect(hInternetOpen, strServer, INTERNET_DEFAULT_HTTP_PORT, vbNullString, "HTTP/1.0", INTERNET_SERVICE_HTTP, 0&, 0&)
    If Not hInternetConnect = 0 Then
      hHttpOpenRequest = HttpOpenRequest(hInternetConnect, "POST", URLPathEncode(strScript), "HTTP/1.0", vbNullString, 0&, INTERNET_FLAG_RELOAD, 0&)
      If Not hHttpOpenRequest = 0 Then

        strHeader = "Content-Type: application/x-www-form-urlencoded" & vbCrLf
        Call HttpSendRequest(hHttpOpenRequest, strHeader, Len(strHeader), strPost, Len(strPost))

        Do
          strRead = vbNullString
          blnLoop = InternetReadFile(hHttpOpenRequest, strRead, Len(strRead), lngOfRead)
          strResult = (strResult & PHP2CRLF(Left$(strRead, lngOfRead)))
          If Not CBool(lngOfRead) Or Not blnLoop Then Exit Do
        Loop

        Call InternetCloseHandle(hInternetOpen)
        Call InternetCloseHandle(hInternetConnect)
        Call InternetCloseHandle(hHttpOpenRequest)
      End If
    End If
  End If
  POSTForm = strResult
End Function

Private Function PHP2CRLF(ByVal strText As String) As String
Dim i As Long
Dim strOut As String
Dim intAsc As Integer
  For i = 1 To Len(strText)
    intAsc = Asc(Mid$(strText, i, 1))
    Select Case intAsc
          Case 13
          Case 10
            strOut = (strOut & vbCrLf)
          Case Else
            strOut = (strOut & Chr$(intAsc))
    End Select
  Next
  PHP2CRLF = strOut
End Function

Public Function URLEncode(ByVal bstrIn As String) As String
Dim i As Long
Dim Char As String
  For i = Len(bstrIn) To 1 Step -1
    Char = Mid$(bstrIn, i, 1)
    Select Case Asc(UCase$(Char))
    Case vbKey0 To vbKey9, vbKeyA To vbKeyZ
    Case 32
      Mid$(bstrIn, i, 1) = "+"
    Case Else
      bstrIn = Left$(bstrIn, i - 1) & "%" & Hex2(Asc(Char)) & Mid$(bstrIn, i + 1)
    End Select
  Next i
URLEncode = bstrIn
End Function

Private Function URLPathEncode(ByVal bstrIn As String) As String
Const ValidChars = "!#$&*+-./:?@_~"
Dim i As Long
Dim Char As String
  For i = Len(bstrIn) To 1 Step -1
    Char = Mid$(bstrIn, i, 1)
    Select Case Asc(UCase$(Char))
    Case vbKey0 To vbKey9, vbKeyA To vbKeyZ
    Case Else
      If InStr(ValidChars, Char) = 0 Then
        bstrIn = Left$(bstrIn, i - 1) & "%" & Hex2(Asc(Char)) & Mid$(bstrIn, i + 1)
      End If
    End Select
  Next i
URLPathEncode = bstrIn
End Function

'Hex2 for URLPathEncode, URLEncode
Private Function Hex2(ByVal n As Long) As String
  If n And &HF0& Then
    Hex2 = Hex$(n)
      Else
    Hex2 = "0" & Hex$(n)
  End If
End Function

' ------------------- modul slut ---------------------

Opret så en form med to textBox'e: 'txtNavn' og 'txtEmail', en multiLine textBox: 'txtReturn' - og en knap: 'cmdPost':

Option Explicit

Private Sub cmdPost_Click()
    Dim strPost As String

    ' Husk at bruge URLEncode() så alle tegn bliver rigtige.
    strPost = "navn=" & URLEncode(txtNavn.Text) & "&"
    strPost = strPost & "email=" & URLEncode(txtEmail.Text)
   
    'MsgBox strPost
   
    ' POSTForm(server navn eller IP, path og script, post string)
    txtReturn.Text = POSTForm("www.domain.dk", "sti/til/vbPostForm.php", strPost)
End Sub

' ------------------- form slut ---------------------

Testfilen 'vbPostForm.php' kunne se sådan sådan ud:

Informationer er modtaget:
  <?=$_POST["navn"]."\n"?>
  <?=$_POST["email"]."\n"?>

' ------------------- phpfil slut ---------------------

/mvh
</bole>
Avatar billede sjh Nybegynder
17. januar 2006 - 21:32 #4
punnishment: Jo.. med Winsock kan du lave de fleste protocol-typer som bruger UDP eller TCP (SMTP, POP3, HTTP, IRC osv..)

Du her er manuel over "Hypertext Transfer Protocol" (HTTP) http://rfc.net/rfc1945.html der kan du læse om hvordan den virker med kommandoer osv..

ellers kan du tag en snyser her : http://www.winsockvb.com/ da plejer at være nogle gode eksempler.. ellers også kan du bruge den kode som ole har sendt.. (Nok det nemmest) ;)
Avatar billede punnishment Nybegynder
17. januar 2006 - 21:32 #5
olebole...mange tak for din bidrag, og jeg er ikke i tvivl om at en lille omskrivning faktisk godt kan gavne mit projekt. Men nu har du nok lidt mere forstand på den kode end mig. Derfor må jeg hellere sige hvad jeg egentlig er ude på:

Du har som sådan godt fat i hvad jeg vil i første omgang. Udfylde en formular og submitte siden. Det eneste jeg sådan set mangler i din kode er at få returneret al HTMl på den "vbPostForm.php" - fil du omtaler - hvordan kan jeg gøre det?
Avatar billede sjh Nybegynder
17. januar 2006 - 21:40 #6
Ja "vbPostForm.php" er jo kun et eksempel på at poste data til en php-side.. men du kunne jo prøve med fx.

txtReturn.Text = POSTForm("www.eksperten.dk", "spm/679847", strPost)

så skulle du meget gerne få alt HTML fra denne side..
Avatar billede olebole Juniormester
17. januar 2006 - 21:50 #7
PHP-filen er blot et eksempel, der viser dig, dokumentet faktisk har modtaget de data, du har sendt til det. Det kunne være et hvilket somhelst dokument på en hvilken somhelst server på 'indernettet'  :)

Der kunne også stå:
    txtReturn.Text = POSTForm("www.eksperten.dk", "sti/til/enEllerAndenFil.php", strPost)

- så ville du få returneret noget HTML ... hvis filen altså eksisterer. Skriver du:
    txtReturn.Text = POSTForm("www.eksperten.dk", "", strPost)

- får du således returneret E's forside  ;o)
Avatar billede olebole Juniormester
17. januar 2006 - 21:51 #8
Hehe ... 'OleBoles første lov' siger:
    "Husk at opdatere siden, når du henter en kop kaffe!"  ;D
Avatar billede sjh Nybegynder
17. januar 2006 - 22:01 #9
hæ hæ sådan er det med os kaffe tønder :D Hvordan går det med den JS timer du skulle lave til mig OLEBOLE :D
Avatar billede olebole Juniormester
17. januar 2006 - 22:11 #10
Jeg har haft håret lidt bagud på det seneste (flytning und alles) - men jeg skal komme efter dig, skal jeg  ;D
Avatar billede sjh Nybegynder
17. januar 2006 - 22:17 #11
ha ha glæder mig som et lille barn :D
Avatar billede punnishment Nybegynder
18. januar 2006 - 17:43 #12
ok, mange tak olebole..så vil jeg lige prøve det. Hvis du lige vil smide et svar så jeg kan acceptere?

Også lige for at være sikker: Formerne bruger POST (altså altså: <form method="POST">), er det ikke netop disse type formler koden loader fra?
Avatar billede sjh Nybegynder
18. januar 2006 - 20:30 #13
jo det er også derfor der står "POST" her:

hHttpOpenRequest = HttpOpenRequest(hInternetConnect, "POST", URLPathEncode.....
Avatar billede sjh Nybegynder
18. januar 2006 - 20:49 #14
som sådan poster du ikke selve HTML koden du poster kun de vadier som stå i HEML fx.

<form method="POST" action="/test/vbPostForm.php">
<input type="text" name="navn" value="Et navn">
<input type="text" name="email" value="En email">
</form>

strServer www.name.dk
hInternetConnect = InternetConnect(hInternetOpen, strServer,...

method="POST"
HttpOpenRequest(hInternetConnect, "POST", ...

action="/test/vbPostForm.php"
strScript = "/test/vbPostForm.php"
HttpOpenRequest(hInternetConnect, "POST", URLPathEncode(strScript), ...


name="navn" value="Et navn"
name="email" value="En email"
strPost = "navn=Et navn&email=En email"
HttpSendRequest(hHttpOpenRequest, strHeader, Len(strHeader), strPost, Len(strPost)) ...
Avatar billede sjh Nybegynder
18. januar 2006 - 20:50 #15
husk dog at bruge URLEncode() til vadier
Avatar billede olebole Juniormester
19. januar 2006 - 11:45 #16
- og her er et svar ... og mon ikke sjh burde lægge et også?  ;o)
Avatar billede sjh Nybegynder
19. januar 2006 - 12:59 #17
ha ha Jeg har fået point for den kode en gang.. så gi du bare ole dem ;)
http://vbhansen.dk/spm/644446
Avatar billede olebole Juniormester
19. januar 2006 - 13:05 #18
*LoL* så er det zq dig, jeg har den fra ... nuvel, det er ikke den eneste af mine VB-snips, der kommer fra den kant  :D
Avatar billede sjh Nybegynder
19. januar 2006 - 13:48 #19
ha ha man kan da altid se at det er mig som har kodet det.. se bare på min stil.. LOOOOOOOOOOOOOOOOL
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester