Ja, hierzu benötigst Du einen COM error handler. IE bringt die Möglichkeit für einen COM error handler mit.
Danke,
ich habs jetzt "einfach" so gelöst...
Ja, hierzu benötigst Du einen COM error handler. IE bringt die Möglichkeit für einen COM error handler mit.
Danke,
ich habs jetzt "einfach" so gelöst...
Ich probiere mal den Ansatz mit Controller/Worker Skript.
Sobald ich was habe, poste ich hier
Das ist super nett, vielen Dank!
Eine weitere Frage habe ich noch, nach ca 400 Abfragen, wirft mir der EXplore immer eine Fehlermeldung, dass es ein Problem mit der Seite gab und diese neu geladen werden musste.
Das ist ja ok, allerdings crashed dann dort das Script., weil er ja kein HTML mehr abrufen kann.
Kann ich das umgehen? Also sowas wie ein on Error > return ?
$aArray = _Stringbetween($oDivArticle.outerhtml, 'class="ampelbox ampelbox_', '" id="ampel1"')
$aArray = _Stringbetween($oDivArticle^ ERROR
Das erhöht die Durchlaufzeit aber nur um etwas mehr als 10 ms. D.h. wir sind bei 4500 Durchläufen immer noch bei gut eienr Stunde.
Kann es sein, dass die Durchlaufzeiten erheblich schwanken? Vielleicht sollte man mal für 50 Durchläufe die jeweilgie Gesamtzeit messen.
Kannst Du bitte das aktuelle Skript posten?
Ich habe mich vertan in meinem ersten Post, ich sehe das erst jetzt, - ich meine 14.500 Abfragen, nicht "nur" 4.500. Sorry
Grad mal laufen lassen, bei 100 Abfragen bin ich bei 112,1 Sekunden.
$File = @ScriptDir & "\Abgleich.csv"
$Results = @ScriptDir & "\Results.csv"
$Link = "https://www.wmkat.de/WMOBS/Artikelsuche/"
$oIE = _IECreate($Link, 0, 0, 1, 0)
FileWrite($Results, "WesselsArt;IntArt;Lieferbar" & @CRLF)
$FileArray = FileReadToArray($File)
Local $iLineCount = @extended
For $i = 0 To $iLineCount - 1
$ID_Split = StringSplit(StringReplace($FileArray[$i], ".", ""), ";")
_IENavigate($oIE, $Link & "1/" & $ID_Split[1] & "/-1", 1)
$oDivArticle = _IEGetObjById($oIE, "artikel_" & $ID_Split[1])
$aArray = _Stringbetween($oDivArticle.outerhtml, 'class="ampelbox ampelbox_', '" id="ampel1"')
If StringRight(_ArrayToString($aArray), 3) = "een" Then $Status = 1
$aArray = _Stringbetween($oDivArticle.outerhtml, 'class="ampelbox ampelbox_', '" id="ampel2"')
If StringRight(_ArrayToString($aArray), 3) = "low" Then $Status = 2
$aArray = _Stringbetween($oDivArticle.outerhtml, 'class="ampelbox ampelbox_', '" id="ampel3"')
If StringRight(_ArrayToString($aArray), 3) = "nge" Then $Status = 0
FileWrite($Results, $ID_Split[1] & ";" & $ID_Split[2] & ";" & $Status & @CRLF)
ToolTip($i, 10, 10)
$Status = 0
Next
Alles anzeigen
Alles anzeigenDa _IENavigate und _IELoadWait jeweils unter 1 Sekunde dauerte, sollte man noch _IEGetObjById messen.
Irgendwie müssen die 4-5 Stunden ja zusammenkommen. _IENavigate und _IELoadWait dauern mit einem gemittelten Gesamtwert von 850 ms weniger als 1 Stunde.In den Raum gefragt (quick & dirty)
Du kannst natürlich ein Controlskript erstellen, das eine beliebige Anzahl an Arbeitsskripten (im Prinzip Dein bisheriges Skript) startet und jeweils als Parameter den Index für den Startlink sowie die Anzahl der Links übergibt.
Die Ergebnisse schreibt jedes Arbeitsskript in eine eigene Datei.
Der Start des Arbeitsskriptes bekommt jeweils die PID des Prozesses zurück. Dieser wird in enem Array gespeichert.
Das Controlskript prüft die Arbeitsprozesse anhand der PID auf Existenz. Wenn alle beendet sind, dann kann das Controlscript die Ergebnisse zu einer Gesamtergebnisdatei zusammenkopieren (falls notwendig).
Danke, habs mal angefügt.
_IEGetObjById dauerte 9.2462
_Stringbetween($oDivArticle.outerhtml) #1 dauert 0.4115
_Stringbetween($oDivArticle.outerhtml) #2 dauert 0.3141
_Stringbetween($oDivArticle.outerhtml) #3 dauert 0.3848
So in etwa:
- Die schreibenden Dateizugriffe habe ich auf Handle umgestellt
- _IENavigate habe ich in zwei Befehle aufgespalten. _IENavigate und _IELoadWait. Beide werden für den ersten Durchlauf ausgewertet und das Ergebnis auf die Konsole ausgegeben.
- Den Umbau von _FileCountLines überlasse ich Dir
Code Alles anzeigenGlobal $Status = 0 $oIE1 = _IECreate("https://www.LINK", 0, 0, 1, 0) ;~ If FileExists(@ScriptDir & "\Results.csv") Then FileDelete(@ScriptDir & "\Results.csv") Global $hResults = FileOpen(@ScriptDir & "\Results.csv") ; Öffne die Ergebnisdatei und speichere das Dateihandle FileWrite($hResults, "Art;IntArt;Result" & @CRLF) ; Alle Schreibbefehle verwenden nun das Dateihandle $FileSize = _FileCountLines(@ScriptDir & "\Compare.csv") For $i = 1 To $FileSize Step +1 $ID1 = StringReplace(FileReadLine(@ScriptDir & "\Compare.csv", $i), ".", "") $ID_String1 = StringSplit($ID1, ";") If $i = 1 Then ; Laufzeit für _IE Funktion bei der ersten Seite ermitteln $hTimer = TimerInit() _IENavigate($oIE1, "https://www.LINK" & $ID_String1[1] & "/-1", 0) ConsoleWrite("_IENavigate dauerte " & TimerDiff($hTimer & " Millisekunden" & @CRLF) $hTimer = TimerInit() _IELoadWait($oIE1) ConsoleWrite("_IELoadWait dauerte " & TimerDiff($hTimer & " Millisekunden" & @CRLF) Else _IENavigate($oIE1, "https://www.LINK" & $ID_String1[1] & "/-1", 1) EndIf $oDivArticle1 = _IEGetObjById($oIE1, "art_" & $ID_String1[1]) $aArray11 = _StringBetween($oDivArticle1.outerhtml, 'class="abox_', '" id="light1"') If StringRight(_ArrayToString($aArray11), 3) = "een" Then $Status1 = 1 $aArray12 = _StringBetween($oDivArticle1.outerhtml, 'class="abox_', '" id="light2"') If StringRight(_ArrayToString($aArray12), 3) = "low" Then $Status1 = 2 $aArray13 = _StringBetween($oDivArticle1.outerhtml, 'class="abox_', '" id="light3"') If StringRight(_ArrayToString($aArray13), 3) = "nge" Then $Status1 = 0 FileWrite($hResults, $ID_String1[1] & ";" & $ID_String1[2] & ";" & $Status1 & @CRLF) ToolTip($i, 10, 10) $Status1 = 0 Next Fileclose($hResults)
Je nach Laufzeit von _IENavigate und _IELoadWait sehen wir, wo wir den Sparstift ansetzen sollten.
Hallo,
anbei das Ergebnis und der Code
Sichtbarer IExplorer
_IENavigate dauerte 2.6993_IELoadWait dauerte 877.8491+>19:58:25 AutoIt3.exe ended.rc:0
IExplorer im Hintergrund
_IENavigate dauerte 2.478_IELoadWait dauerte 816.9387+>20:01:50 AutoIt3.exe ended.rc:0
Quellcode
$File = @ScriptDir & "\Abgleich.csv"
$Results = @ScriptDir & "\Results.csv"
$Link = "https://www.wmkat.de/WMOBS/Artikelsuche/"
$oIE = _IECreate($Link, 0, 1, 1, 0)
FileWrite($Results, "WesselsArt;IntArt;Lieferbar" & @CRLF)
$FileArray = FileReadToArray($File)
Local $iLineCount = @extended
For $i = 0 To $iLineCount - 1
$ID_Split = StringSplit(StringReplace($FileArray[$i], ".", ""), ";")
_IENavigate($oIE, $Link & "1/" & $ID_Split[1] & "/-1", 1)
If $i = 1 Then ; Laufzeit für _IE Funktion bei der ersten Seite ermitteln
$hTimer = TimerInit()
_IENavigate($oIE, $Link & "/1/" & $ID_Split[1] & "/-1", 0)
ConsoleWrite("_IENavigate dauerte " & TimerDiff($hTimer & " Millisekunden" & @CRLF))
$hTimer = TimerInit()
_IELoadWait($oIE)
ConsoleWrite("_IELoadWait dauerte " & TimerDiff($hTimer & " Millisekunden" & @CRLF))
Else
_IENavigate($oIE, $Link& "/1/" & $ID_Split[1] & "/-1", 1)
EndIf
$oDivArticle = _IEGetObjById($oIE, "artikel_" & $ID_Split[1])
$aArray = _Stringbetween($oDivArticle.outerhtml, 'class="ampelbox ampelbox_', '" id="ampel1"')
If StringRight(_ArrayToString($aArray), 3) = "een" Then $Status = 1
$aArray = _Stringbetween($oDivArticle.outerhtml, 'class="ampelbox ampelbox_', '" id="ampel2"')
If StringRight(_ArrayToString($aArray), 3) = "low" Then $Status = 2
$aArray = _Stringbetween($oDivArticle.outerhtml, 'class="ampelbox ampelbox_', '" id="ampel3"')
If StringRight(_ArrayToString($aArray), 3) = "nge" Then $Status = 0
FileWrite($Results, $ID_Split[1] & ";" & $ID_Split[2] & ";" & $Status & @CRLF)
ToolTip($i, 10, 10)
$Status = 0
Next
Alles anzeigen
Einfach mal in den Raum gefragt, indem man _IENavigate und _IELoadWait trennt... könnte man dann nicht einfach bspw.
-> 10x IEXplore öffnen
-> Jeweils Link 1 - 10 aufrufen
-> Im Nachgang IELoadwait für alle IE Fenster anwenden
-> In die Datei schreiben
-> Die nächsten 10 Links etc....
so verfahren? Sehe wohl blöde aus und ich wüsste jetzt auch nicht wie ich das "sauber" machen kann... aber wenn es performanter wäre... hätte ich ja schon was "gewonnen".
Um die Abfrage zu beschleunigen könntest Du die Datei compare.csv in einen Array einlesen und dann direkt auf die entsprechende Zelle zugreifen. Mit FileReadLine liest Du 4500 mal die Datei bis zur gewünschten Zeile durch.
Das gilt auch für FileWriteLine. Wenn Du den Dateinamen angibst, dann wird die Datei jeweils geöffnet, der Datensatz geschrieben und die Datei wieder geschlossen.
In einem Test mit 4500 Datensätzen dauert das 50848 ms gegenüber 4 ms.
BTW: Wo wird $waitforload definiert?Setze mal einen Timer für _IENavigate. Vielleicht kann man daraus eine eigene Funktion erstellen und gewisse Fehlerprüfungen entfernen.
Hi,
danke für deine Antwort, darüber habe ich auch nachgedacht, da ich das woanders auch nutze. Also ReadtoArray, das werde ich gleich mal umstellen.
Welche Alternative kann ich denn nutzen zum schreiben? Kann ich auch erst in einen anderen Array schreiben lassen? Wie greife ich den denn so ab, dass er in eine Datei schreibt?
$waitforload wurde oben definiert ist aber einfach eine 1, die hatte ich entfernt, die Variable war noch ein Überbleibsel.
- Zum Timer, wie genau meinst du das mit den Fehlerprüfungen und dem Timer? Sorry dazu habe ich jetzt keine Idee.
Vielen Dank.
Ich habs mal mit FileReadToArray gemacht, Geschwindigkeit hat es auf jeden Fall keine (spürbare) gebracht.
Das was hier wohl noch immer am längsten dauert, ist wohl das Laden der Website, wobei die Array Variante natürlich die bessere ist.
Viele Grüße,
Leaves
$File = @ScriptDir & "\Abgleich.csv"
$Results = @ScriptDir & "\Results.csv"
$Link = "https://www.wmkat.de/WMOBS/Artikelsuche/"
$oIE = _IECreate($Link, 0, 0, 1, 0)
FileWrite($Results, "WesselsArt;IntArt;Lieferbar" & @CRLF)
$FileArray = FileReadToArray($File)
Local $iLineCount = @extended
For $i = 0 To $iLineCount - 1
$ID_Split = StringSplit(StringReplace($FileArray[$i], ".", ""), ";")
_IENavigate($oIE, $Link & "1/" & $ID_Split[1] & "/-1", 1)
$oDivArticle = _IEGetObjById($oIE, "artikel_" & $ID_Split[1])
$aArray = _Stringbetween($oDivArticle.outerhtml, 'class="ampelbox ampelbox_', '" id="ampel1"')
If StringRight(_ArrayToString($aArray), 3) = "een" Then $Status = 1
$aArray = _Stringbetween($oDivArticle.outerhtml, 'class="ampelbox ampelbox_', '" id="ampel2"')
If StringRight(_ArrayToString($aArray), 3) = "low" Then $Status = 2
$aArray = _Stringbetween($oDivArticle.outerhtml, 'class="ampelbox ampelbox_', '" id="ampel3"')
If StringRight(_ArrayToString($aArray), 3) = "nge" Then $Status = 0
FileWrite($Results, $ID_Split[1] & ";" & $ID_Split[2] & ";" & $Status & @CRLF)
ToolTip($I, 10, 10)
$Status = 0
Next
Alles anzeigen
Hey, - also mit dem Smart Client, da habe ich auch mal nachgesehen ob man da nicht nen sniffer zwischen hängen kann.
Leider ist der Smart Client aber nix anderes als das WMKAT+, also einfach eine erweiterte Informationsquelle für Werkstätten, das brauch ich nicht.
Auch der DataService, - der angeboten wird, - kann genutzt werden, der ist aber nur hilfreich um alle Artikel zu exportieren. Dadurch habe ich aber leider auch keine Verfügbarkeitsprüfung. Dadurch das ja auch noch die einzelnen Warenhäuser dargestellt werden statt nur das Zentrallager, ist das gar nicht so leicht mit den Abfragen.
Eine Alternative würde ich natürlich nutzen, aber ich habe spezielle Bedarfe die aber teilweise aus Mindermengen bestehen, dafür kriege ich keine Kundenkonten bei HB Behru usw. große Bedarfe decke ich bereits woanders.
Gäbe es denn eine Möglichkeit die Abfrage zu optimieren? Habe über mehrere Handler nachgedacht... oder einfach mehrere Instanzen... aber ich bin mir nicht sicher, wie ich das in "Serie" schalten soll.
Grüße
Dennoch wäre ggf. interessant welche Webseite/Dienst das ist ggf. hat shcon jemand Erfahrung damit, um das mitzuteilen musst du ja keine Logindaten preis geben ;).
Bei der Anzahl an Abfragen hört sich das nicht nach "normalen" Usereingaben an, sondern etwas was durchaus automatisiert über API oder direkt an die Server (ohne die Webseite dazwischen) laufen sollte. Dann solltest du auch um einiges schneller sein.
Hat die Webseite eine API die du nutzen könntest oder direkte Serverabfragen?
Handelt sich um WMKAT, - API gibts da leider nich, habe mit der IT gesprochen, - das Gesuch danach wurde abgelehnt, hätte natürlich auch lieber eine Liste aus dem FTP gefahren.
Hallo zusammen,
ich habe danach gesucht aber leider nichts passendes gefunden.
Ich möchte Werte auslesen, die mir Informationen über Warenbestände liefern.
Allerdings muss ich ca 4.500 Abfragen in Summe senden, das dauert mit meiner jetzigen Methode ewig, ca 4-5 Stunden...
Ich habe die Hoffnung dass mir jemand einen Tipp geben kann, wie ich das eventuell beschleunigen könnte.
Den Link zur Website habe ich entfernt, da hier auch ein Userlogin nötig wäre...
Habe bereits mit dem Anbieter selbst gesprochen, die Abfragen sind i.O. eine Bestandsdatei lässt er mir aber nicht zukommen, weil das so wohl nicht vorgesehen ist.
Deshalb hoffe ich, dass jemand eine clevere Idee hat, die mir weiterhelfen könnte, hier meine zweckmäßige Lösung.
Grüße und vielen Dank im Voraus,
Leaves
Global $Status = 0
$oIE1 = _IECreate("https://www.LINK", 0, 0, 1, 0)
;~ If FileExists(@ScriptDir & "\Results.csv") Then FileDelete(@ScriptDir & "\Results.csv")
FileWrite("Results.csv", "Art;IntArt;Result" & @CRLF)
$FileSize = _FileCountLines(@ScriptDir & "\Compare.csv")
For $i = 1 To $FileSize Step +1
$ID1 = StringReplace(FileReadLine(@ScriptDir & "\Compare.csv", $i), ".", "")
$ID_String1 = StringSplit($ID1, ";")
_IENavigate($oIE1, "https://www.LINK" & $ID_String1[1] & "/-1", $waitforload)
$oDivArticle1 = _IEGetObjById($oIE1, "art_" & $ID_String1[1])
$aArray11 = _Stringbetween($oDivArticle1.outerhtml, 'class="abox_', '" id="light1"')
If StringRight(_ArrayToString($aArray11), 3) = "een" Then $Status1 = 1
$aArray12 = _Stringbetween($oDivArticle1.outerhtml, 'class="abox_', '" id="light2"')
If StringRight(_ArrayToString($aArray12), 3) = "low" Then $Status1 = 2
$aArray13 = _Stringbetween($oDivArticle1.outerhtml, 'class="abox_', '" id="light3"')
If StringRight(_ArrayToString($aArray13), 3) = "nge" Then $Status1 = 0
FileWrite(@ScriptDir & "\Results.csv", $ID_String1[1] & ";" & $ID_String1[2] & ";" & $Status1 & @CRLF)
ToolTip($I, 10, 10)
$Status1 = 0
Next
Alles anzeigen