You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Beautiful Soup find()函数参数使用问题及爬取报错排查

问题描述

我正在学习用Python做网页爬取,写了第一个爬虫脚本,但运行后报错不断,注释掉报错的行又会出现新错误。

部分代码

titolo = soup.find('h1', class_='in-reListCard__title').text.strip()
prezzo = soup.find('li', class_='in-feat__item--main in-detail__mainFeaturesPrice').text.strip()

elemento_locali = soup.find('div', class_='in-feat__data').text.strip()
elemento_superficie = soup.find('li', aria-label='superficie')

print("Elemento Locali:", elemento_locali)
print("Elemento Superficie:", elemento_superficie)

locali = elemento_locali.find('div', class_='in-feat__data').text.strip() if elemento_locali else None
superficie = elemento_superficie.find('div', class_='in-feat__data').text.strip() if elemento_superficie else None

爬取目标页面:米兰市中心房源列表页

遇到的错误

  1. 第一处错误:

expression cannot contain assignment, perhaps you meant "=="?
related to elemento_superficie = soup.find('li', aria-label='superficie')

  1. 注释掉上述报错行后,出现新错误:

line 42, in
titolo = soup.find('h1', class_='in-reListCard__title').text.strip()
AttributeError: 'NoneType' object has no attribute 'text'

请问是不是Beautiful Soup的find()参数用错了?还是有其他问题?

完整代码

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import NoSuchElementException
from bs4 import BeautifulSoup
import pandas as pd
import requests

dati_immobili = []

with open('quartieri.txt', 'r') as file_quartieri:
    info_quartieri = [line.strip() for line in file_quartieri.readlines()]

with open('quartieri.txt', 'r') as file:
    voci_list = [line.strip() for line in file.readlines()]

url_base = 'https://www.immobiliare.it/vendita-case/milano/'

driver = webdriver.Safari()

for voce, info_quartiere in zip(voci_list, info_quartieri):
    # Scorrimento su pagine successive
    url = f'{url_base}{voce}/?page='
    page_num = 1

    while True:
        url_completo = f'{url}{page_num}'
        driver.get(url_completo)

        try:
            soup = BeautifulSoup(driver.page_source, 'html.parser')

            # Estrai i dati desiderati
            titolo = soup.find('h1', class_='in-reListCard__title').text.strip()
            prezzo = soup.find('li', class_='in-feat__item--main in-detail__mainFeaturesPrice').text.strip()

            elemento_locali = soup.find('div', class_='in-feat__data').text.strip()
##            elemento_superficie = soup.find('li', aria-label='superficie')

            print("Elemento Locali:", elemento_locali)
            print("Elemento Superficie:", elemento_superficie)

            locali = elemento_locali.find('div', class_='in-feat__data').text.strip() if elemento_locali else None
            superficie = elemento_superficie.find('div', class_='in-feat__data').text.strip() if elemento_superficie else None

            # Aggiungi i dati a una lista
            dati_immobili.append({
                'Titolo': titolo,
                'Prezzo': prezzo,
                'Locali': locali,
                'Superficie': superficie,
                'InfoQuartiere': info_quartiere
            })

            # Incrementa il numero di pagina
            page_num += 1

        except NoSuchElementException:
            break

driver.quit()

# Converti la lista di dati in un DataFrame
df = pd.DataFrame(dati_immobili)

# Esporta il DataFrame in un file Excel
df.to_excel('dati_immobili.xls', index=False)

问题分析与解决

1. aria-label参数的语法错误

你写的elemento_superficie = soup.find('li', aria-label='superficie')会报错,因为Python参数名不能包含连字符-。Beautiful Soup处理带连字符的HTML属性时,有两种正确写法:

# 方法一:用字典传递属性
elemento_superficie = soup.find('li', {'aria-label': 'superficie'})

# 方法二:用下划线替代连字符(Beautiful Soup自动转换)
elemento_superficie = soup.find('li', aria_label='superficie')

2. AttributeError: 'NoneType' object has no attribute 'text'

这个错误说明soup.find()没找到目标元素,返回了None,直接调用.text就会报错,核心问题有两个:

  • 选择器逻辑错误:目标页面是房源列表页,你直接全局查找h1.in-reListCard__title,但列表页的房源标题其实是每个卡片内的h2标签,不是全局的h1;同理,价格、房间数等字段也需要先定位到单条房源卡片,再在卡片内提取。
  • 缺少空值判断:即使选择器正确,也可能存在房源缺失字段的情况,必须先判断元素是否存在,再调用.text。

修复后的核心提取逻辑

先定位所有房源卡片,再逐个提取数据:

# 等待页面加载完成(避免未渲染就解析)
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, 'in-reListCard')))

soup = BeautifulSoup(driver.page_source, 'html.parser')
# 找到所有房源卡片
cards = soup.find_all('div', class_='in-reListCard')

for card in cards:
    # 提取标题:先判断元素是否存在
    titolo_tag = card.find('h2', class_='in-reListCard__title')
    titolo = titolo_tag.text.strip() if titolo_tag else '无标题'
    
    # 提取价格
    prezzo_tag = card.find('li', class_='in-feat__item--main in-detail__mainFeaturesPrice')
    prezzo = prezzo_tag.text.strip() if prezzo_tag else '无价格'
    
    # 提取房间数
    locali_tag = card.find('div', class_='in-feat__data')
    locali = locali_tag.text.strip() if locali_tag else '无数据'
    
    # 提取面积
    superficie_tag = card.find('li', {'aria-label': 'superficie'})
    superficie_data = superficie_tag.find('div', class_='in-feat__data') if superficie_tag else None
    superficie = superficie_data.text.strip() if superficie_data else '无数据'
    
    dati_immobili.append({
        'Titolo': titolo,
        'Prezzo': prezzo,
        'Locali': locali,
        'Superficie': superficie,
        'InfoQuartiere': info_quartiere
    })

3. 其他优化点

  • 重复读取文件:两次打开quartieri.txt可以合并,若两个列表内容相同,直接复制即可:
    with open('quartieri.txt', 'r') as file:
        voci_list = [line.strip() for line in file.readlines()]
    info_quartieri = voci_list.copy()
    
  • 异常捕获范围:仅捕获NoSuchElementException不够,建议扩大捕获范围或在每个元素提取时做空值判断,避免脚本中途崩溃。

内容的提问来源于stack exchange,提问作者FuzzyOperator

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 07:08:12