2010-07-13 14 views
13

Ich Scraping eine Seite mit Python Pyquery, und ich bin irgendwie verwirrt durch die Typen, die es zurückgibt, und insbesondere, wie man über eine Liste von Ergebnissen iterieren.Iterieren über Objekte in Pyquery

Wenn mein HTML ein bisschen wie folgt aussieht:

<div class="formwrap">blah blah <h3>Something interesting</h3></div> 
<div class="formwrap">more rubbish <h3>Something else interesting</h3></div> 

Wie kann ich das Innere der <h3> Tags bekommen, eins nach dem anderen, so kann ich sie bearbeiten? Ich versuche:

results_page = pq(response.read()) 
formwraps = results_page(".formwrap") 
print type(formwraps) 
print type([formwraps]) 
for my_div in [formwraps]: 
    print type(my_div) 
    print my_div("h3").text() 

Dies erzeugt:

<class 'pyquery.pyquery.PyQuery'> 
<type 'list'> 
<class 'pyquery.pyquery.PyQuery'> 
Something interesting something else interesting 

Es sieht aus, als gäbe es keine wirkliche Iteration geht. Wie kann ich jedes Element einzeln herausziehen?

Zusätzliche Frage von einem Neuling: Was sind die eckigen Klammern um [a] tun? Es sieht so aus, als ob es ein spezielles Pyquery-Objekt in eine Liste konvertiert. Ist [] ein Standard-Python-Operator?

------ -------- UPDATE

Ich habe ein 'jeder' function in the pyquery docs gefunden. Ich verstehe jedoch nicht, wie ich es für das verwenden soll, was ich will. Sagen wir, ich möchte nur den Inhalt der <h3> ausdrucken. Dies führt zu einem Syntaxfehler: Warum?

formwraps.each(lambda e: print e("h3").text()) 

Antwort

7

ich nie pyquery verwendet habe, aber die Quelle des Syntaxfehlers ist, dass Lambda-Ausdrücke in Python ist so eine Art beschränkt, können Sie nur innerhalb eine expresion verwenden (also keine Aussagen wie print). Sie können umgehen diese Einschränkung der Verwendung einer Funktion, z:

def my_print(x): 
    print x 

formwraps.each(lambda e: my_print(e("h3").text())) 
9

Ich glaube, Sie so etwas tun kann:

from pyquery import PyQuery as pq 

def get_h3_contents(index, node): 
    d = pq(node) 
    d.find('h3').text() 

formwraps.each(get_h3_contents) 

Hoffnung, dass jemand, wenn nicht das ursprüngliche Plakat hilft.

3

Ich glaube, Sie über pyquery wie diese iterieren könnte:

for i in range(len(formwraps)): 
    print(formwraps.eq(i)) 
    ... 
4

Sie es auch tun können ohne die each Methode:

from pyquery import PyQuery as pq 
html = """ 
<div class="formwrap">blah blah <h3>Something interesting</h3></div> 
<div class="formwrap">more rubbish <h3>Something else interesting</h3></div> 
""" 
formwraps = pq(html)(".formwrap") 

for my_div in formwraps: 
    print pq(my_div)("h3").text() 

Es produziert die folgende Ausgabe:

Something interesting 
Something else interesting 
16

Seit pyquery 1.2.3 (commit) können Sie items() ein PyQuery Objekt verwenden für so PyQuery Objekt durch jedes Element gehen:

print(type(formwraps.items())) 
for my_div in formwraps.items(): 
    print(my_div("h3").text()) 

Verfahren items() ein generator zurückkehrt und dies funktioniert sowohl Python 2 und 3.

4

letzte pyquery Versionen ermöglichen Ihnen die Verwendung von .items()

[h.text() for h in formwraps('h3').items()]