it-swarm.com.de

Wörterbuchliste erstellen Python

Ich möchte alle iframe von einer Webseite erhalten.

Code:

site = "http://" + url
f = urllib2.urlopen(site)
web_content =  f.read()

soup = BeautifulSoup(web_content)
info = {}
content = []
for iframe in soup.find_all('iframe'):
    info['src'] = iframe.get('src')
    info['height'] = iframe.get('height')
    info['width'] = iframe.get('width')
    content.append(info)
    print(info)       

pprint(content)

ergebnis von print(info):

{'src': u'abc.com', 'width': u'0', 'height': u'0'}
{'src': u'xyz.com', 'width': u'0', 'height': u'0'}
{'src': u'http://www.detik.com', 'width': u'1000', 'height': u'600'}

ergebnis von pprint(content):

[{'height': u'600', 'src': u'http://www.detik.com', 'width': u'1000'},
{'height': u'600', 'src': u'http://www.detik.com', 'width': u'1000'},
{'height': u'600', 'src': u'http://www.detik.com', 'width': u'1000'}]

Warum stimmt der Wert des Inhalts nicht? Es wird angenommen, dass es derselbe Wert ist, wenn ich print(info).

27
l1th1um

Sie erstellen nicht für jeden iFrame ein eigenes Wörterbuch, sondern ändern immer wieder dasselbe Wörterbuch und fügen dem Wörterbuch in Ihrer Liste weitere Verweise hinzu.

Denken Sie daran, dass Sie beim Ausführen von content.append(info) keine Kopie der Daten erstellen, sondern lediglich einen Verweis an die Daten anhängen.

Sie müssen für jeden iframe ein neues Wörterbuch erstellen.

for iframe in soup.find_all('iframe'):
   info = {}
    ...

Noch besser ist, dass Sie nicht erst ein leeres Wörterbuch erstellen müssen. Erstellen Sie einfach alles auf einmal:

for iframe in soup.find_all('iframe'):
    info = {
        "src":    iframe.get('src'),
        "height": iframe.get('height'),
        "width":  iframe.get('width'),
    }
    content.append(info)

Es gibt andere Möglichkeiten, um dies zu erreichen, z. B. das Durchlaufen einer Liste von Attributen oder das Verwenden von Listen- oder Wörterbuchverständnissen. Die Klarheit des obigen Codes lässt sich jedoch nur schwer verbessern.

54
Bryan Oakley

Sie haben das Objekt Python list falsch verstanden. Es ähnelt einem C pointer-array. Es "kopiert" nicht das Objekt, das Sie daran anhängen. Stattdessen wird nur ein "Zeiger" auf dieses Objekt gespeichert.

Versuchen Sie den folgenden Code:

>>> d={}
>>> dlist=[]
>>> for i in xrange(0,3):
    d['data']=i
    dlist.append(d)
    print(d)

{'data': 0}
{'data': 1}
{'data': 2}
>>> print(dlist)
[{'data': 2}, {'data': 2}, {'data': 2}]

Warum ist print(dlist) nicht dasselbe wie print(d)?

Der folgende Code zeigt Ihnen den Grund:

>>> for i in dlist:
    print "the list item point to object:", id(i)

the list item point to object: 47472232
the list item point to object: 47472232
the list item point to object: 47472232

Sie können also sehen, dass alle Elemente in dlist tatsächlich auf dasselbe dict Objekt zeigen.

Die eigentliche Antwort auf diese Frage besteht darin, die "Kopie" des Zielobjekts mit d.copy() anzuhängen.

>>> dlist=[]
>>> for i in xrange(0,3):
    d['data']=i
    dlist.append(d.copy())
    print(d)

{'data': 0}
{'data': 1}
{'data': 2}
>>> print dlist
[{'data': 0}, {'data': 1}, {'data': 2}]

Versuchen Sie den Trick id(). Sie können sehen, dass die Listenelemente tatsächlich auf ganz andere Objekte verweisen.

>>> for i in dlist:
    print "the list item points to object:", id(i)

the list item points to object: 33861576
the list item points to object: 47472520
the list item points to object: 47458120
33
Wang

info ist ein Zeiger auf ein Wörterbuch - Sie fügen immer wieder denselben Zeiger zu Ihrer Liste hinzu contact.

Fügen Sie info = {} In die Schleife ein und es sollte das Problem lösen:

...
content = []
for iframe in soup.find_all('iframe'):
    info = {}
    info['src'] = iframe.get('src')
    info['height'] = iframe.get('height')
    info['width'] = iframe.get('width')
...
3
zenpoy

Wenn Sie eine Zeile möchten:

list_of_dict = [{} for i in range(list_len)]
3
XU Bin