【问题标题】:Using Beautiful Soup to find specific class使用 Beautiful Soup 查找特定类
【发布时间】:2017-05-31 22:42:15
【问题描述】:

我正在尝试使用 Beautiful Soup 从 Zillow 抓取房价数据。

我通过属性 id 获取网页,例如。 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 个结果,都是 &lt;div&gt;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)

【问题讨论】:

    标签: python html web-scraping beautifulsoup


    【解决方案1】:

    您的 HTML 格式不正确,在这种情况下,选择正确的解析器至关重要。在BeautifulSoup 中,目前有 3 个可用的 HTML 解析器以不同的方式工作和处理损坏的 HTML

    • html.parser(内置,无需额外模块)
    • lxml(最快,需要安装lxml
    • html5lib(最宽松,需要安装html5lib

    Differences between parsers 文档页面更详细地描述了这些差异。在您的情况下,为了证明差异:

    >>> 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 没有。

    【讨论】:

    • @RobBenz 确保你有 from bs4 import BeautifulSoup 导入 - 我看到另一个答案建议 from BeautifulSoup import BeautifulSoup,这不好 - 这是 BeautifulSoup 版本 3 导入 - 这个版本已经过时并且没有维护.
    • @RobBenz 同样,如果您只需要摘要元素,您可以使用SoupStrainer 加快解析速度,只解析所需元素而不是整个树。
    【解决方案2】:
    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'
    

    我也得到了这个工作 - 但看起来有人打败了我。

    无论如何都要发帖。

    【讨论】:

    • 嗯,这很有趣。只需使用不同的解析器就可以了。我很好奇这是否比在搜索之前美化 HTML 更快。我将不得不对此进行测试。谢谢!
    • 是的,很抱歉第一行的错字,复制和粘贴错误;现已修复
    【解决方案3】:

    根据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()
    

    【讨论】:

    • 成功了。我尝试通过肉眼寻找丢失的标签,但代码太多。 W3.org Validator 是我不知道的一个很好的资源。谢谢!
    猜你喜欢
    • 2016-10-07
    • 1970-01-01
    • 1970-01-01
    • 2019-11-23
    • 1970-01-01
    • 2012-02-18
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    相关资源
    最近更新 更多