python - 使用具有相同 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')
'''
解决方案
那个工程:
{'Bedrooms' : Listing.text} if Listing.text else 'N/A'
'N/A'
如果Listing.text
是None
或如果Listing.text
是空字符串,将获得该值。以前的 禁用了这种可能性if
。
if 'Bedrooms:' in Listing.text:
bedrooms.append({'Bedrooms' : Listing.text} if Listing.text else 'N/A')
如果我们进入之后的块if
不Listing.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
这个实现下降m²
。如果你想包含它,你可以使用:
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²
实施取决于您未显示的详细信息。
推荐阅读
- c - C中贪心算法的输出没有给我任何输出
- javascript - 更改许多父属性而不将它们全部写出来
- linux - 如何在 rrdtool 图中按时间段聚合数据
- python - 重新采样数据帧,插入 NaN 并返回数据帧
- laravel - 使用 Sendinblue 从 Laravel 应用程序发送数据
- javascript - formik 组件正在将文本类型的受控输入更改为不受控制
- android - 如何使用 Toothpick 对 android ViewModels 使用构造函数注入
- reactjs - 条件反应属性
- java - Java DerInputStream.getLength():lengthTag=109
- json - 如何以良好的格式查看 JSON 文件?