提取不平衡列表中的项目 - BeautifulSoup

时间:2018-03-12 14:41:34

标签: python web-scraping beautifulsoup

我正在抓取房地产数据格式化为表格格式。某些属性没有完全相同的细节。例如 - 一块土地不包含有关卧室数量的信息。

<div class="srp-item-property-meta">
    <ul class="property-meta list-horizontal list-style-disc list-spaced">
        <li data-label="property-meta-beds"><span class="data-value meta-
        beds">3</span> bd</li>
        <li data-label="property-meta-baths"><span class="data-
        value">1</span> ba</li>
        <li data-label="property-meta-sqft"><span class="data-
        value">1,224</span> sq ft</li>
        <li data-label="property-meta-lotsize"><span class="data-
        value">6,098</span> sq ft lot</li>
    </ul>
</div>

VS。

<div class="srp-item-property-meta">
    <ul class="property-meta list-horizontal list-style-disc list-spaced">
        <li data-label="property-meta-lotsize"><span class="data-
        value">3.1</span> acre lot</li>
    </ul>
</div>

如果我正在尝试使用BeautifulSoup

house = {"beds": [], "baths": [], "lotsize": []}

for beds in soup.find_all("li", {"data-label": "property-meta-beds"}):
    house["beds"].append(beds.text)

for lot in soup.find_all("li", {"data-label": "property-meta-lotsize"}):
    house["lotsize"].append(lot.text)

我想将所有属性组合到一个数据框中。但是当循环到达一个缺少一条信息的属性,而不是返回NA或NONE或类似的东西时,它只是继续前进,所以我的列表最终会有不同数量的实体,并且它们没有排列。

链接:https://www.realtor.com/realestateandhomes-search/48198

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

您可以按如下方式平衡您的列表:

from bs4 import BeautifulSoup
import requests

url = "https://www.realtor.com/realestateandhomes-search/48198"
user_agent = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1'
html = requests.get(url, headers={'User-Agent':user_agent}).text
soup = BeautifulSoup(html, "html.parser")

house = {"beds": [], "baths": [], "lotsize": []}

for div in soup.select('div.srp-item-property-meta'):
    for label, tag in [('property-meta-beds', 'beds'), ('property-meta-baths', 'baths'), ('property-meta-lotsize', 'lotsize')]:
        li = div.ul.find('li', {'data-label':label})
        house[tag].append(li.text if li else 'None')

print(house)

这会给你house包含:

{
  'beds': ['3 bd', '3 bd', '3 bd', '3 bd', '3 bd', '3 bd', '2 bd', '2 bd', '3 bd', 'None', 'None', '3 bd', '3 bd', '3 bd', '3 bd'], 
  'baths': ['1+ ba', '1 ba', '2 ba', '1 ba', '1 ba', '2 ba', '2 ba', '2 ba', '1 ba', 'None', 'None', '1 ba', '2 ba', '2 ba', '1+ ba'], 
  'lotsize': ['None', '7,405 sq ft lot', '5,663 sq ft lot', '6,098 sq ft lot', '8,712 sq ft lot', '7,405 sq ft lot', '2,178 sq ft lot', 'None', '7,841 sq ft lot', '2.1 acres lot', '2.24 acres lot', '5,663 sq ft lot', 'None', 'None', '7,405 sq ft lot']
}

如果找不到给定的data-label,则会附加None

答案 1 :(得分:0)

看看是否添加了if / then帮助:

house = {"beds": [], "baths": [], "lotsize": []}

for li in soup.find_all("li"):
    if li.has_attr("data-label"):
        label = li.attrs["data-label"]
        if label == "property-meta-beds":
           house["beds"].append(li.text)
        else:
           house["beds"].append("NA")

        if label == "property-meta-baths":
            house["baths"].append(li.text)
        else:
            house["baths"].append("NA")

        if label == "property-meta-lotsize":
           house["lotsize"].append(li.text)
        else:
           house["lotsize"].append("NA")

答案 2 :(得分:0)

要解决不平衡列表问题,您可以创建字典列表,而不是列表字典。

代码:

r = requests.get('https://www.realtor.com/realestateandhomes-search/48198')
soup = BeautifulSoup(r.text, 'lxml')

houses = []

for prop in soup.find_all('div', class_='srp-item-property-meta'):
    house = {}

    beds = prop.find('span', class_='data-value meta-beds')
    if beds:
        house['beds'] = beds.text

    lot = prop.find('li', {'data-label': 'property-meta-lotsize'})
    if lot:
        house['lotsize'] = lot.span.text

    houses.append(house)

print(houses)

输出:

[{'beds': '3'},
 {'beds': '3', 'lotsize': '7,405'},
 {'beds': '3', 'lotsize': '5,663'},
 {'beds': '3', 'lotsize': '6,098'},
 {'beds': '3', 'lotsize': '8,712'},
 {'beds': '3', 'lotsize': '7,405'},
 {'beds': '2', 'lotsize': '2,178'},
 {'beds': '2'},
 {'beds': '3', 'lotsize': '7,841'},
 {'lotsize': '2.1'},
 {'lotsize': '2.24'},
 {'beds': '3', 'lotsize': '5,663'},
 {'beds': '3'},
 {'beds': '3'},
 {'beds': '3', 'lotsize': '7,405'}]

您使用类似的逻辑来获取其他详细信息。