首页 > 解决方案 > 使用具有相同 div 的 BeautifulSoup 进行 Web 解析 - 如果在页面上找不到,则无法返回“N/A”

问题描述

所以我试图抓取整个网站,但问题是该页面与我想要的条目使用相同。所以这就是为什么我要为它做 findAll 然后用 if: 语句寻找各个参数。

我当前的问题是我无法让所有参数的长度都相同,因为某些页面没有该参数。这也意味着如果列长度不同,我无法将其导出到 csv。

此外,使用当前代码时,它不会在未找到时返回“N/A”。

这是我的代码(可能也不是最有效的)

'''
response = requests.get(url)
soup = BeautifulSoup(response.text, "html.parser")
header = soup.find('p', attrs={'class':'ho1'}).text
location.append({'Location' : header.partition(split)[2]} if header else 'N/A')
for Listing in soup.findAll('div', attrs={'style' : "height:19px; line-height:19px; color:#333; display:inline; float:left"}):
    print(Listing)
    if 'ID: ' in Listing.text:
        identification.append({'ID' : Listing.text} if Listing.text else 'N/A')
    if 'Bedrooms:' in Listing.text:
        bedrooms.append({'Bedrooms' : Listing.text} if Listing.text else 'N/A')
    if 'Bathrooms: ' in Listing.text:
        bathrooms.append({'Bathrooms' : Listing.text} if Listing.text else 'N/A')
    if 'Type: ' in Listing.text:
        typetotal.append({'Type' : Listing.text} if Listing.text else 'N/A')

'''

标签: pythonparsingweb-scrapingbeautifulsoup

解决方案


那个工程:

{'Bedrooms' : Listing.text} if Listing.text else 'N/A'

'N/A'如果Listing.textNone或如果Listing.text是空字符串,将获得该值。以前的 禁用了这种可能性if

if 'Bedrooms:' in Listing.text:
        bedrooms.append({'Bedrooms' : Listing.text} if Listing.text else 'N/A')

如果我们进入之后的块ifListing.text为空。

也许你的意思是:

bedrooms.append({'Bedrooms' : Listing.text} if 'Bedrooms:' in Listing.text else 'N/A')

这仍然不是最佳的,但它是对您的代码的最小修正。

更新#1

在您的新示例中,所有项目都列在一个没有分隔符的字符串中。在这种情况下,您应该首先提取值。例如使用正则表达式。

import re

l_text = 'ID: 225671 Type: Apartment Size: 300 m²  Bedrooms: 3  Bathrooms: 3  '

pat_id = r'ID:\s*(\d+)'
pat_bedrooms = r'Bedrooms:\s*(\d+)'
pat_apt_size = r'Apartment Size:\s*(\d+)\s*m²'
pat_id2 = r'ID2:\s*(\d+)'

res = re.search(pat_id, l_text)
val_id = res.group(1) if res else 'N/A'

res = re.search(pat_id2, l_text)
val_id2 = res.group(1) if res else 'N/A'

res = re.search(pat_bedrooms, l_text)
val_bedrooms = res.group(1) if res else 'N/A'

res = re.search(pat_apt_size, l_text)
val_apt_size = res.group(1) if res else 'N/A'


print(val_id, val_id2, val_bedrooms, val_apt_size)

输出:

225671 N/A 3 300

或者您可以使用通用模式:

pat_any = r'([A-Z][^:]*):\s*(\d+)'
res = re.findall(pat_any, l_text)
res = {k:v for k,v in res}

val_id = res.get('ID', 'N/A')
val_id2 = res.get('ID2', 'N/A')
val_bedrooms = res.get('Bedrooms', 'N/A')
val_apt_size = res.get('Apartment Size', 'N/A')

print(val_id, val_id2, val_bedrooms, val_apt_size)

输出:

225671 N/A 3 300

这个实现下降。如果你想包含它,你可以使用:

pat_any = r'([A-Z][^:]*):\s*([^A-Z]+)'
res = re.findall(pat_any, l_text)
res = {k:v.strip() for k,v in res}

val_id = res.get('ID', 'N/A')
val_id2 = res.get('ID2', 'N/A')
val_bedrooms = res.get('Bedrooms', 'N/A')
val_apt_size = res.get('Apartment Size', 'N/A')

print(val_id, val_id2, val_bedrooms, val_apt_size)

输出:

225671 N/A 3 300 m²

实施取决于您未显示的详细信息。


推荐阅读