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
爬取目标页面:米兰市中心房源列表页
遇到的错误
- 第一处错误:
expression cannot contain assignment, perhaps you meant "=="?
related to elemento_superficie = soup.find('li', aria-label='superficie')
- 注释掉上述报错行后,出现新错误:
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
相关产品推荐
相关产品推荐

