Hallo,
bin relativ neu in Python und versuche eine Liste/Dictionary (assoziatives Array) aus der folgenden Webdatei zu generieren:
[codebox=html5 file=Unbenannt.html]<html><head>
<meta http-equiv="content-type" content="text/html"></head><body>{ 0: "File1.exe",
1: "File14.exe",
2: "File7.exe",
3: "File90.exe",
4: "File100.exe",
23: "File23.exe",
700: "File19.exe",
}</body></html>[/code]
Das technische herunterladen und Verarbeiten mit BS klappt gut. Im Ergebnis möchte ich die Wertepaare (0 : File1.exe....), die nicht fortlaufend sind, über eien Schleife iterieren und verarbeiten können. Wisst Ihr evtl., wie das geht?
Vielen Dank!
Dictionary aus Webdatei generieren
@python64: Wo kommen die Daten denn her? Warum ist das fast JSON aber dann in HTML verpackt und eben doch nicht ganz JSON? Kann man das nicht in einem vernünftigen Standardformat bekommen, beispielsweise JSON?
Du müsstest mal nach einer API für die Seite suchen, also ob irgendwo json ausgeliefert wird.
Hintergrund für die Rückfrage ist, dass es mit dem json-Modul eine eigene Bibliothek in der Standardbibliothek gibt, die mit json-Objekten umgehen kann, was den Umweg über ein Abrufen und Parsen der Seite unnötig machen würde.
https://docs.python.org/3/library/json.html
Hintergrund für die Rückfrage ist, dass es mit dem json-Modul eine eigene Bibliothek in der Standardbibliothek gibt, die mit json-Objekten umgehen kann, was den Umweg über ein Abrufen und Parsen der Seite unnötig machen würde.
https://docs.python.org/3/library/json.html
@python64: Dann würde ich `ast.literaleval()` vorschlagen und hoffen das die Webseite nichts liefert was damit nicht verarbeitet werden kann.
Code: Alles auswählen
In [47]: source = '''
...: { 0: "File1.exe",
...: 1: "File14.exe",
...: 2: "File7.exe",
...: 3: "File90.exe",
...: 4: "File100.exe",
...: 23: "File23.exe",
...: 700: "File19.exe",
...: }
...: '''
In [48]: ast.literal_eval(source)
Out[48]:
{0: 'File1.exe',
1: 'File14.exe',
2: 'File7.exe',
3: 'File90.exe',
4: 'File100.exe',
23: 'File23.exe',
700: 'File19.exe'}
Vielen Dank! Habs jetzt anders gelöst, vermutlich unelegant, aber funktioniert:
<body> mir BS auslesen und dann den String zurechtbasteln:
>>File14.exe
<body> mir BS auslesen und dann den String zurechtbasteln:
Code: Alles auswählen
def getSite(url):
try:
bsObj = BeautifulSoup(html.read(), "html.parser")
allText = bsObj.find('body')
except AttributeError as e:
return None
return allText
allText = getSite(http://...)
......
str1 = allText.text
str1 = str1.replace("\t", "")
str1 = str1.replace("\r\n", "")
str1 = str1.replace(":", " :")
str1 = str1.replace(",", ", ")
str1 = str1.replace(", }", "}")
str1 = re.sub(r'(\d*) :', r'"\1":', str1)
resp = json.loads(str1)
print(resp["1"])
Zuletzt geändert von Anonymous am Dienstag 1. August 2017, 19:26, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
@python64: Was soll denn in den zwei Zeilen zu einem `AttributeError` führen und wieviel Sinn macht es in dem Fall `None` als Ergebnis zu liefern? Entweder liefert man da beispielsweise eine leere Zeichenkette, oder noch besser, man meldet das als Ausnahme weiter. Eventuell sogar in dem man die vorhandene Ausnahme einfach gar nicht in der Funktion behandelt.
`Obj` ist ein unsinniger Namenszusatz. *Alles* was man in Python an einen Namen binden kann ist ein Objekt. Also könnte man an *jeden* Namen `Obj` anhängen, aber es gibt halt bei keinem Namen einen Mehrwert, denn das es ein Objekt ist, ist ja eh klar.
Warum gibt die Funktion das `Element`-Objekt zurück und nicht einfach den Text? Und `getSite()` verspricht mehr als da passiert. Eine Website ist die Gesamtheit aller zusammengehörenden Webseiten hinter einer Domain.
Einige Namen halten sich nicht an die Namenschreibweise aus dem Style Guide for Python Code und Abkürzungen und unsinnige angehängte Nummern sollte man bei Namen nicht verwenden.
Unelegant ist das eine, aber das sieht nicht wirklich robust aus. Zumal der `ast.literal_eval()`-Aufruf wesentlich kürzer ist.
`Obj` ist ein unsinniger Namenszusatz. *Alles* was man in Python an einen Namen binden kann ist ein Objekt. Also könnte man an *jeden* Namen `Obj` anhängen, aber es gibt halt bei keinem Namen einen Mehrwert, denn das es ein Objekt ist, ist ja eh klar.
Warum gibt die Funktion das `Element`-Objekt zurück und nicht einfach den Text? Und `getSite()` verspricht mehr als da passiert. Eine Website ist die Gesamtheit aller zusammengehörenden Webseiten hinter einer Domain.
Einige Namen halten sich nicht an die Namenschreibweise aus dem Style Guide for Python Code und Abkürzungen und unsinnige angehängte Nummern sollte man bei Namen nicht verwenden.
Unelegant ist das eine, aber das sieht nicht wirklich robust aus. Zumal der `ast.literal_eval()`-Aufruf wesentlich kürzer ist.
Code: Alles auswählen
from urllib.request import urlopen, Request
from urllib.error import HTTPError
from bs4 import BeautifulSoup
import ast
def getUrl(url):
try:
html = urlopen(Request(url))
except HTTPError as e:
print(e)
return None
try:
bs = BeautifulSoup(html.read(), "html.parser")
allText = bs.find('body')
except AttributeError as e:
print(e)
return None
return allText.text
allText = getUrl("http://....")
if allText == None:
print("Generator could not be found")
else:
dict = ast.literal_eval(allText)
print(dict[0])
Zuletzt geändert von Anonymous am Mittwoch 2. August 2017, 15:24, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Schau Dir mal das requests-Modul an, ist einfacher in der Handhabung als das urllib-Teil...
http://docs.python-requests.org/en/master/
http://docs.python-requests.org/en/master/