salve,
ich möchte von ca. 20 verschiedenen seiten die lieferbarkeit von produkten abfragen, indem ich die html seiten parse.
ich habe das erst in php geschrieben, geht auch, ist aber sehr langsam....dauert gut 30 sekunden, weil das halt alles sequentiell gemacht wird.
ich habe gehört mit python kann man mehrere urls gleichzeitig öffnen und parsen, nennt sich wohl multithreading. leider finde ich nirgens ein beispiel.
hat jemand ein script an dem ich mich orientieren kann ? oder geht das auch ohne multithreading ?
thnx
d
mehrere urlopen gleichzeitig ?
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hallo debian75!debian75 hat geschrieben:ich habe gehört mit python kann man mehrere urls gleichzeitig öffnen und parsen, nennt sich wohl multithreading. leider finde ich nirgens ein beispiel.
Willkommen im Python-Forum!
Ich sag's dir gleich vorab: Threading ist für den Anfang nicht einfach. Aber vielleicht kannst du trotzdem etwas damit anfangen.
Dieses Beispiel ist aber nicht ideal, da es genau so viele Threads öffnet, wie es URLs gibt. Und es versucht alle URLs gleichzeitig zu erreichen und die Daten zurück zu bekommen. Bei 30 URLs die gleichzeitig abgefragt werden, kann das evt. Probleme bereiten. Probier es einfach mal aus.
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-
import urllib2
import threading
import time
lock = threading.Lock()
def download(url, retvals):
try:
html = urllib2.urlopen(url).read()
except urllib2.URLError, exception:
html = "ERROR: %s" % str(exception)
lock.acquire()
retvals.append((url, html))
lock.release()
def main():
urls = (
"http://gerold.bcom.at/",
"http://halvar.at/",
"http://lugt.at/",
"http://microsoft.de/",
"http://www.python-forum.de/",
"http://python.org/",
"http://wallerforum.com/",
#"http://log-in.fachdid.fu-berlin.de/Archiv/2001/2/Thema/", # braucht zu lange
)
retvals = []
threads = []
for url in urls:
threads.append(
threading.Thread(
target = download, kwargs = dict(url = url, retvals = retvals)
)
)
threads[-1].start()
time.sleep(0.2)
# Warten bis alle fertig sind
for thread in threads:
thread.join()
for url, html in retvals:
print url
if html.startswith("ERROR"):
print "Achtung Fehler!"
print html[:100]
print
if __name__ == "__main__":
main()
mfg
Gerold
Zuletzt geändert von gerold am Dienstag 27. November 2007, 11:31, insgesamt 1-mal geändert.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
hallo
ich nochmal. ich habe jetzt dieses script in die datei "m.py" kopiert. leider bekomme ich einen fehler wenn ich m.py über den browser aufrufen will.
"The server encountered an internal error or misconfiguration and was unable to complete your request."
----
----
was mach ich falsch ?
Edit by Gerold: Code-Tags gesetzt. Beim nächsten mal bitte selber machen.
ich nochmal. ich habe jetzt dieses script in die datei "m.py" kopiert. leider bekomme ich einen fehler wenn ich m.py über den browser aufrufen will.
"The server encountered an internal error or misconfiguration and was unable to complete your request."
----
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-
import os
import urllib
import urllib2
import threading
import time
print 'Content-Type: text/html\n\n'
lock = threading.Lock()
def download(url, retvals):
try:
html = urllib2.urlopen(url).read()
except urllib2.URLError, exception:
html = "ERROR: %s" % str(exception)
lock.acquire()
retvals.append((url, html))
lock.release()
def main():
urls = (
"http://www.google.com/",
"http://www.gmail.com/",
#"http://log-in.fachdid.fu-berlin.de/Archiv/2001/2/Thema/", # braucht zu lange
)
retvals = []
threads = []
for url in urls:
threads.append(
threading.Thread(
target = download, kwargs = dict(url = url, retvals = retvals)
)
)
threads[-1].start()
time.sleep(0.2)
# Warten bis alle fertig sind
for thread in threads:
thread.join()
for url, html in retvals:
print url
if html.startswith("ERROR"):
print "Achtung Fehler!"
print html[:100]
print
main()
was mach ich falsch ?
Edit by Gerold: Code-Tags gesetzt. Beim nächsten mal bitte selber machen.
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hallo!
Du willst das also als CGI ausführen. Da kann vieles schief laufen. Zu niedere Python-Version. Falscher Pfad zu Python im Kopf. Falsches Encoding (aber nicht in diesem Fall). ...
- [wiki]CGI[/wiki]
- [wiki]Web-Skripte zum Laufen bringen[/wiki]
Vielleicht bekommst du eine bessere Fehlermeldung mit:
im Kopf deines Programms.
Und dann noch dieser Hinweis: http://www.python-forum.de/faq.php#21
mfg
Gerold
Du willst das also als CGI ausführen. Da kann vieles schief laufen. Zu niedere Python-Version. Falscher Pfad zu Python im Kopf. Falsches Encoding (aber nicht in diesem Fall). ...
- [wiki]CGI[/wiki]
- [wiki]Web-Skripte zum Laufen bringen[/wiki]
Vielleicht bekommst du eine bessere Fehlermeldung mit:
Code: Alles auswählen
import cgi
import cgitb; cgitb.enable()
Und dann noch dieser Hinweis: http://www.python-forum.de/faq.php#21
mfg
Gerold
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
danke, ich les mich da mal durch. anbei mal meine ausgangslage, nicht lachen, ist erst mein zweiter tag mit python
das hier funktioniert so, ich will halt jetzt nur noch mehrere urls gleichzeitig losrennen lassen:
das script soll die lieferzeit von büchern verschiedener online shops prüfen:
das hier funktioniert so, ich will halt jetzt nur noch mehrere urls gleichzeitig losrennen lassen:
das script soll die lieferzeit von büchern verschiedener online shops prüfen:
Code: Alles auswählen
#!/usr/bin/python
#print 'Content-Type: text/html\n\n'
import os
import urllib
import urllib2
import threading
import time
print 'Content-Type: text/html\n\n'
#EAN ist sowas wie die ISBN nummer von einem buch
def geturltest(ean):
url = 'http://www.foobar.ch/search.aspx?some=params'
page = urllib.urlopen(url)
pagedata = page.read()
return pagedata
def strpos(string,search):
pos = string.find(search)
return pos
def test(string,pos):
return string[pos+5:pos+12]
page = geturltest('9783280071465')
position = strpos(page,"Lieferzeit")
print test(page,position)
Zuletzt geändert von debian75 am Dienstag 27. November 2007, 15:44, insgesamt 1-mal geändert.
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Jetzt wirds ärgelich: http://www.python-forum.de/faq.php#21
Du kannst mit dem "Edit"-Button deinen Beitrag editieren.
Du kannst mit dem "Edit"-Button deinen Beitrag editieren.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
sorry, hatte ich ned gesehengerold hat geschrieben:Jetzt wirds ärgelich: http://www.python-forum.de/faq.php#21
Du kannst mit dem "Edit"-Button deinen Beitrag editieren.
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
mfggerold hat geschrieben:Vielleicht bekommst du eine bessere Fehlermeldung mit:im Kopf deines Programms.Code: Alles auswählen
import cgi import cgitb; cgitb.enable()
Gerold
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
uhm....neues problem.
ich benutze den code so ziemlich wie vorgeschlagen. nur, wenn ein server nicht erreichbar ist, dann blockiert er die weitere verarbeitung.
gibt es eine möglichkeite einem thread zu sagen, er solle es nur 5 sekunden versuchen und wenn er dann nicht fertig ist aufhören ?
weil sonst hängt mein programm wegen diesem einen thead.
ich benutze den code so ziemlich wie vorgeschlagen. nur, wenn ein server nicht erreichbar ist, dann blockiert er die weitere verarbeitung.
gibt es eine möglichkeite einem thread zu sagen, er solle es nur 5 sekunden versuchen und wenn er dann nicht fertig ist aufhören ?
weil sonst hängt mein programm wegen diesem einen thead.
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hallo!
Das eingebaute Timeout ist, glaube ich, bei 30 Sekunden angesetzt. Mehr weiß ich jetzt auch nicht. Vielleicht hilft ein Blick in den Quellcode von urllib2.
mfg
Gerold
Das eingebaute Timeout ist, glaube ich, bei 30 Sekunden angesetzt. Mehr weiß ich jetzt auch nicht. Vielleicht hilft ein Blick in den Quellcode von urllib2.
mfg
Gerold
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.