web-dev-qa-db-ja.com

Beautiful Soupを使用して特定のクラスを見つける

Beautiful Soupを使用して、Zillowから住宅価格のデータを取得しようとしています。

プロパティIDでWebページを取得します。 http://www.zillow.com/homes/for_sale/18429834_zpid/

find_all()関数を試しても結果が得られません。

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

ただし、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>

2つの結果が得られます。両方とも<div>sクラスhome-summary-row。だから、私の質問は、ページ全体を検索するとなぜ結果が得られないのですか?


作業例:

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)
6
SFBA26

W3.org Validator によると、HTMLには、閉じた閉じタグや複数行に分割されたタグなど、多くの問題があります。例えば:

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

この種類のマークアップは、BeautifulSoupがHTMLを解析することをはるかに困難にする可能性があります。

各行の末尾から改行や末尾のスペースを削除するなど、HTMLをクリーンアップするために何かを実行してみてください。 BeautifulSoupは、HTMLツリーをクリーンアップすることもできます。

from BeautifulSoup import BeautifulSoup
tree = BeautifulSoup(bad_html)
good_html = tree.prettify()
3
Soviut

あなたのHTMLは整形式ではありません。このような場合、適切なパーサーを選択することが重要です。 BeautifulSoup には、現在3つの利用可能なHTMLパーサーがあり機能し、壊れたHTMLを異なる方法で処理します

  • html.parser(組み込み、追加モジュールは不要)
  • lxml(最速、lxmlのインストールが必要)
  • html5lib(最も緩い、html5libのインストールが必要)

パーサー間の違い のドキュメントページでは、違いについて詳しく説明しています。あなたのケースでは、違いを示すために:

>>> 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

ご覧のとおり、あなたのケースでは、html.parserlxmlの両方が仕事をしますが、html5libはしません。

5
alecxe
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'

私もこれを機能させました-しかし、誰かが私を倒したようです。

とにかく投稿します。

4
RobBenz