2017-01-17 3 views
3

Ich versuche, schöne Suppe zu verwenden, um Wohnungspreisdaten von Zillow zu kratzen.Unter Verwendung der schönen Suppe, um spezifische Klasse zu finden

Ich bekomme die Webseite nach Eigenschaft ID, z. http://www.zillow.com/homes/for_sale/18429834_zpid/

Wenn ich die find_all() Funktion versuchen, ich erhalte keine Ergebnisse:

results = soup.find_all('div', attrs={"class":"home-summary-row"}) 

Allerdings, wenn ich die HTML-nehmen und es bis auf die Lautstärke nur die Bits Ich möchte, zB .:

<html> 
    <body> 
     <div class=" status-icon-row for-sale-row home-summary-row"> 
     </div> 
     <div class=" home-summary-row"> 
      <span class=""> $1,342,144 </span> 
     </div> 
    </body> 
</html> 

Ich bekomme 2 Ergebnisse, beide <div> s mit der Klasse home-summary-row. Also, meine Frage ist, warum bekomme ich keine Ergebnisse beim Durchsuchen der ganzen Seite?


Arbeitsbeispiel:

from bs4 import BeautifulSoup 
import requests 

zpid = "18429834" 
url = "http://www.zillow.com/homes/" + zpid + "_zpid/" 
response = requests.get(url) 
html = response.content 
#html = '<html><body><div class=" status-icon-row for-sale-row home-summary-row"></div><div class=" home-summary-row"><span class=""> $1,342,144 </span></div></body></html>' 
soup = BeautifulSoup(html, "html5lib") 

results = soup.find_all('div', attrs={"class":"home-summary-row"}) 
print(results) 

Antwort

2

Nach dem W3.org Validator, gibt es eine Reihe von Problemen mit dem HTML wie Streuschließenden Tags und Tags über mehrere Zeilen aufgeteilt. Zum Beispiel:

<a 
href="http://www.zillow.com/danville-ca-94526/sold/" title="Recent home sales" class="" data-za-action="Recent Home Sales" > 

Diese Art von Markup kann es BeautifulSoup viel schwieriger machen, HTML zu parsen.

Sie können versuchen, etwas auszuführen, um den HTML-Code zu bereinigen, z. B. Entfernen der Zeilenumbrüche und nachgestellten Leerzeichen am Ende jeder Zeile. BeautifulSoup können auch die HTML-Struktur für Sie aufzuräumen:

from BeautifulSoup import BeautifulSoup 
tree = BeautifulSoup(bad_html) 
good_html = tree.prettify() 
+0

Das hat den Trick gemacht. Ich habe versucht, fehlende Tags mit dem Auge zu suchen, aber es gab zu viel Code. W3.Der Validator ist eine großartige Ressource, die mir nicht bekannt war. Vielen Dank! – SFBA26

4
import requests 
from bs4 import BeautifulSoup 

zpid = "18429834" 
url = "http://www.zillow.com/homes/" + zpid + "_zpid/" 

r = requests.get(url) 

soup = BeautifulSoup(r.content, "lxml") 

g_data = soup.find_all("div", {"class": "home-summary-row"}) 

print g_data[1].text 

#for item in g_data: 
#  print item("span")[0].text 
#  print '\n' 

Ich habe dies zu arbeiten - aber es sieht aus wie jemand mich darauf schlagen.

werde sowieso post.

+0

Hm, das ist interessant. Einfach einen anderen Parser zu verwenden, hat es funktioniert. Ich bin gespannt, ob das schneller ist als das HTML vor der Suche zu verschönern. Ich werde das testen müssen. Vielen Dank! – SFBA26

+0

Yep, Entschuldigung für Tippfehler in der ersten Zeile, Copy & Paste-Fehler; jetzt behoben – RobBenz

4

Ihr HTML ist nicht gut gebildet und in Fällen wie diesem ist die Wahl des richtigen Parser entscheidend. In BeautifulSoup gibt es derzeit 3 ​​verfügbaren HTML-Parser die Arbeit und gebrochene HTML handhaben anders:

  • html.parser (eingebaut, keine zusätzlichen Module erforderlich)
  • lxml (die schnellste, erfordert lxml installiert werden
  • )
  • html5lib (das milde, erfordert html5lib
installiert) werden

die Differences between parsers Dokumentationsseite beschreibt die Unterschiede genauer. In Ihrem Fall, um den Unterschied zu demonstrieren:

>>> from bs4 import BeautifulSoup 
>>> import requests 
>>> 
>>> zpid = "18429834" 
>>> url = "http://www.zillow.com/homes/" + zpid + "_zpid/" 
>>> response = requests.get(url) 
>>> html = response.content 
>>> 
>>> len(BeautifulSoup(html, "html5lib").find_all('div', attrs={"class":"home-summary-row"})) 
0 
>>> len(BeautifulSoup(html, "html.parser").find_all('div', attrs={"class":"home-summary-row"})) 
3 
>>> len(BeautifulSoup(html, "lxml").find_all('div', attrs={"class":"home-summary-row"})) 
3 

Wie Sie sehen können, in Ihrem Fall, beide html.parser und lxml die Arbeit tun, aber html5lib nicht.

+0

@RobBenz stellen Sie sicher, Sie haben 'von bs4 Import BeautifulSoup' Import - Ich sah die andere Antwort vorschlagen' BeautifulSoup Import BeautifulSoup', die nicht gut ist - das ist die BeautifulSoup Version 3 Import - diese Version ist ziemlich veraltet und nicht beibehalten. – alecxe

+0

@RobBenz auch, wenn Sie nur die Zusammenfassung Elemente benötigen, können Sie ['SoupStrainer'] (https://www.crummy.com/software/BeautifulSoup/bs4/doc/#parsing-only-part-of-a -document), um das Parsen und Parsen nur der gewünschten Elemente anstelle des gesamten Baums zu beschleunigen. – alecxe

+0

Tolle Infos, danke – RobBenz

Verwandte Themen