Seite 1 von 2

WebGadget - wie den gesamten Inhalt selektieren

Verfasst: 21.07.2016 17:03
von Kurzer
Hallo,

ich versuche an den dargestellten Inhalt eines Webgadgets zu kommen.
Die Inhalte werden per Script erzeugt, daher sind die von mir benötigten Daten bei einem Download des HTML-Quellcodes nicht enthalten.
Gibt es eine Möglichkeit den Text im Webgadget per PB zu selektieren? Ich würde ihn dann über das Clipboard abgreifen.

Möglicherweise gibt es noch eine andere Möglichkeit? Ich bin für alle Vorschläge offen.

Gruß Kurzer

Re: WebGadget - wie den gesamten Inhalt selektieren

Verfasst: 21.07.2016 17:26
von RSBasic
Ja, mit der PB-Funktion kannst du nur den originalen, unveränderten Quellcode ermitteln, aber versuche mal mit folgendem Code: http://www.rsbasic.de/aktualisierung/wi ... mitteln.pb
Damit solltest du den vollständigen HTML-Quelltext ermitteln können.
Das Problem hatte ich auch, als ich einen automatisierten Google-Übersetzer für WinAPI Library entwickeln wollte.

Ansonsten siehe WinAPI Library\WebGadget\: Da findest du auch andere Beispiele wie z.B. "Markierten Text ermitteln", falls du sowas brauchst.
Ich hoffe, ich konnte dir helfen.

Re: WebGadget - wie den gesamten Inhalt selektieren

Verfasst: 21.07.2016 18:37
von edel

Re: WebGadget - wie den gesamten Inhalt selektieren

Verfasst: 21.07.2016 23:09
von Kurzer
Besten Dank euch beiden! :allright:

Es scheint beides ähnlich zu sein. Leider ist der code, auf den Edel verweist, recht alt und fehlerhaft (illegaler Speicherzugriff in Zeile 21).

Ich habe mich nicht länger mit der Korrektur des zweiten Beispiels aufgehalten, weil der Code von RSBasic wunderbar funktioniert und ich relativ schnell eine Lösung für ein Tool bei uns in der Firma brauchte. Klappt erste Sahne... damit sparen wir uns einen Haufen manuelle Arbeit!

Gruß Kurzer

Re: WebGadget - wie den gesamten Inhalt selektieren

Verfasst: 22.07.2016 08:37
von Kurzer
Mist, da habe ich mich zu früh gefreut. :shock:

Unter Windows 10 (teste das jetzt auf Arbeit) bekomme ich mit dieser Methode fast das gleiche zurück wie mit GetGadgetItemText().
Unter Win XP bekomme ich den kompletten gerenderten HTML Code zurück.

Habt ihr dazu eine Idee wie ich das Ergebnis auch unter Windows 10 bekommen kann?

Gruß Kurzer

Re: WebGadget - wie den gesamten Inhalt selektieren

Verfasst: 22.07.2016 09:28
von RSBasic
Kannst du einen kleinen Beispielcode anfertigen?
Leider habe ich keinen Code zum Nachstellen und mit der Google Translator-Seite funktioniert es unter Windows 10 auch.

Re: WebGadget - wie den gesamten Inhalt selektieren

Verfasst: 22.07.2016 10:50
von Kurzer
Ja mache ich. Das Problem ist allerdings, dass ich Dir die verwendete URL nicht geben kann.
An der Seite muss man sich einloggen und auch den Inhalt, den ich verarbeite, darf ich aus Datenschutzgründen nicht öffentlich machen (es geht um Kundendaten).

Hier aber trotzdem ein Beispiel, mit dem es mir unter Windows 10 nicht gelingt den Seiteninhalt einer per Script erzeugten Adresstabelle abzugreifen.

Oben bei den Konstanten müsstest Du die URL anpassen und das Laufwerk. Der Code erzeugt auf dem laufwerk zwei Dateien mit dem jeweils ermittelten Webseiteninhalt.

Danke für Deine Hilfe. :allright:

Gruß Kurzer

Code: Alles auswählen

EnableExplicit

Define.s sHTML
#Drive = "F:\"
#URL = "https://www.google.de/maps"
Procedure.i WebGadget_Document(iGadget, *IID)
  Protected.i iDocument = 0
  Protected.i iBrowser.IWebBrowser2
  Protected.i iDocumentDispatch.IDispatch
  
  iBrowser.IWebBrowser2 = GetWindowLongPtr_(GadgetID(iGadget), #GWL_USERDATA)
  If iBrowser
    If iBrowser\get_Document(@iDocumentDispatch.IDispatch) = #S_OK And iDocumentDispatch
      iDocumentDispatch\QueryInterface(*IID, @iDocument)
      iDocumentDispatch\Release()
    EndIf
  EndIf     
  
  ProcedureReturn iDocument
EndProcedure
Procedure.s WebGadget_GetFullHtml(iGadget.i)
  Protected.s sResult = ""
  Protected.i iDocument.IHTMLDocument3
  Protected.i iRoot.IHTMLElement
  Protected.i ibstr_html
  
  iDocument.IHTMLDocument3 = WebGadget_Document(iGadget, ?IID_IHTMLDocument3)
  If iDocument
    If iDocument\get_documentElement(@iRoot.IHTMLElement) = #S_OK
      If iRoot\get_outerHTML(@ibstr_html) = #S_OK And ibstr_html
        sResult = PeekS(ibstr_html, -1, #PB_Unicode)
        SysFreeString_(ibstr_html)
      EndIf
      
      iRoot\Release()
    EndIf                       
    iDocument\Release()
  EndIf         
  
  ProcedureReturn sResult
EndProcedure

  If OpenWindow(0, 0, 0, 1024, 600, "WebGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) 
  	WebGadget(0, 10, 10, 1004, 580, #URL) 
  	
  	Repeat : Delay(1) : Until WaitWindowEvent() = #PB_Event_CloseWindow Or GetGadgetAttribute(0, #PB_Web_Busy) = 0
  	
  	; Quellcode mit der PB Methode ermitteln
  	sHTML=GetGadgetItemText(0, #PB_Web_HtmlCode)
  	If CreateFile(0, #Drive + "WebGadget_GetItemText.txt")
  		WriteData(0, @sHTML, Len(sHTML)*SizeOf(Character))
  		CloseFile(0)
  	EndIf
  	
  	; Quellcode mit der von RSBsic erwähnten Methode ermitteln
  	sHTML=WebGadget_GetFullHtml(0)
  	If CreateFile(0, #Drive + "WebGadget_IHTMLDocument3.txt")
  		WriteData(0, @sHTML, Len(sHTML)*SizeOf(Character))
  		CloseFile(0)
  	EndIf
		
    Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow 
  EndIf

DataSection
  IID_IHTMLDocument2: ; {332C4425-26CB-11D0-B483-00C04FD90119}
  Data.l $332C4425
  Data.w $26CB, $11D0       
  Data.b $B4, $83, $00, $C0, $4F, $D9, $01, $19
  IID_IHTMLDocument3: ; {3050F485-98B5-11CF-BB82-00AA00BDCE0B}
  Data.l $3050F485
  Data.w $98B5, $11CF
  Data.b $BB, $82, $00, $AA, $00, $BD, $CE, $0B
  IID_NULL: ; {00000000-0000-0000-0000-000000000000}
  Data.l $00000000
  Data.w $0000, $0000
  Data.b $00, $00, $00, $00, $00, $00, $00, $00
EndDataSection

Re: WebGadget - wie den gesamten Inhalt selektieren

Verfasst: 22.07.2016 11:20
von RSBasic
Hallo Kurzer,

wenn du in deiner Eventschleife eine Debug-Zeile einfügst, wirst du feststellen, dass der Save-Code nur einmal am Anfang ausgeführt wird.
Möchtest du in Google Maps beispielsweise die Adresse ermitteln, die erst später nach dem Setzen des Markers auf der rechten Seite angezeigt wird?
Bild

Falls ja, dann kann ich mit dem von mir leicht angepassten Code die Adresse ermitteln, die ich mit GetGadgetItemText() nicht ermitteln kann:

Code: Alles auswählen

EnableExplicit

Define.s sHTML
#Drive = "D:\"
#URL = "https://www.google.de/maps"
Procedure.i WebGadget_Document(iGadget, *IID)
  Protected.i iDocument = 0
  Protected.i iBrowser.IWebBrowser2
  Protected.i iDocumentDispatch.IDispatch
  
  iBrowser.IWebBrowser2 = GetWindowLongPtr_(GadgetID(iGadget), #GWL_USERDATA)
  If iBrowser
    If iBrowser\get_Document(@iDocumentDispatch.IDispatch) = #S_OK And iDocumentDispatch
      iDocumentDispatch\QueryInterface(*IID, @iDocument)
      iDocumentDispatch\Release()
    EndIf
  EndIf     
  
  ProcedureReturn iDocument
EndProcedure
Procedure.s WebGadget_GetFullHtml(iGadget.i)
  Protected.s sResult = ""
  Protected.i iDocument.IHTMLDocument3
  Protected.i iRoot.IHTMLElement
  Protected.i ibstr_html
  
  iDocument.IHTMLDocument3 = WebGadget_Document(iGadget, ?IID_IHTMLDocument3)
  If iDocument
    If iDocument\get_documentElement(@iRoot.IHTMLElement) = #S_OK
      If iRoot\get_outerHTML(@ibstr_html) = #S_OK And ibstr_html
        sResult = PeekS(ibstr_html, -1, #PB_Unicode)
        SysFreeString_(ibstr_html)
      EndIf
      
      iRoot\Release()
    EndIf                       
    iDocument\Release()
  EndIf         
  
  ProcedureReturn sResult
EndProcedure

If OpenWindow(0, 0, 0, 1024, 600, "WebGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  WebGadget(0, 10, 10, WindowWidth(0)-20, WindowHeight(0)-50, #URL)
  ButtonGadget(1, WindowWidth(0)-210, WindowHeight(0)-30, 200, 20, "Quellcode speichern", 0)
  
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 1
            ; Quellcode mit der PB Methode ermitteln
            sHTML=GetGadgetItemText(0, #PB_Web_HtmlCode)
            If CreateFile(0, #Drive + "WebGadget_GetItemText.txt")
              WriteData(0, @sHTML, Len(sHTML)*SizeOf(Character))
              CloseFile(0)
            EndIf
            
            ; Quellcode mit der von RSBsic erwähnten Methode ermitteln
            sHTML=WebGadget_GetFullHtml(0)
            If CreateFile(0, #Drive + "WebGadget_IHTMLDocument3.txt")
              WriteData(0, @sHTML, Len(sHTML)*SizeOf(Character))
              CloseFile(0)
            EndIf
        EndSelect
      Case #PB_Event_CloseWindow
        End
    EndSelect
  ForEver
EndIf

DataSection
  IID_IHTMLDocument2: ; {332C4425-26CB-11D0-B483-00C04FD90119}
  Data.l $332C4425
  Data.w $26CB, $11D0       
  Data.b $B4, $83, $00, $C0, $4F, $D9, $01, $19
  IID_IHTMLDocument3: ; {3050F485-98B5-11CF-BB82-00AA00BDCE0B}
  Data.l $3050F485
  Data.w $98B5, $11CF
  Data.b $BB, $82, $00, $AA, $00, $BD, $CE, $0B
  IID_NULL: ; {00000000-0000-0000-0000-000000000000}
  Data.l $00000000
  Data.w $0000, $0000
  Data.b $00, $00, $00, $00, $00, $00, $00, $00
EndDataSection

Re: WebGadget - wie den gesamten Inhalt selektieren

Verfasst: 22.07.2016 11:34
von Kurzer
Aha! Interessant.

Das Problem liegt offenbar an der Erkennung, wann die Webseite komplett geladen und gerendert ist.

Nehme ich Deinen code und meine URL, dann funktionert es (nach Klick auf den Button).
Also muss ich mal nachforschen, warum diese Schleife (aus meinem Beispiel) unter Win 10 zu früh verlassen wird:

Code: Alles auswählen

Repeat
  Delay(1)
Until WaitWindowEvent() = #PB_Event_CloseWindow Or GetGadgetAttribute(0, #PB_Web_Busy) = 0

Re: WebGadget - wie den gesamten Inhalt selektieren

Verfasst: 22.07.2016 11:43
von RSBasic
Das Problem wird wohl sein, dass die nachträglichen Informationen mit Ajax nachgeladen werden. Ich bin mir nicht sicher, ob Ajax bei #PB_Web_Busy ebenfalls berücksichtigt wird. Ich glaube, das bezieht sich nur auf das normale Laden der Seite.
Du kannst alternativ einen Timer nutzen, um verzögert den Quellcode auszulesen.