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

使用Beautiful Soup爬取Mecca护肤页面遇AttributeError及数据获取问题

问题与解决方案

问题概述

爬取Mecca护肤页面的产品品牌、名称及成分列表,已成功获取产品链接,但提取具体信息时要么无结果返回,要么触发AttributeError: 'NoneType' object has no attribute 'text'错误。

核心原因

  1. 动态CSS类名:页面中使用的css-738lkl、css-pdiqc3这类类名是动态生成的,会随页面更新变化,无法稳定定位元素。
  2. 请求头缺失:直接用requests发送请求会被网站识别为爬虫,返回不完整的静态HTML,无法获取实际渲染的内容。
  3. 动态内容加载:部分产品信息可能通过JavaScript异步加载,静态请求无法获取。

解决方案

1. 补充请求头模拟浏览器访问

添加User-Agent等请求头,避免被反爬机制拦截:

import requests
from bs4 import BeautifulSoup

# 模拟浏览器请求头
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'
}

# 修正产品链接拼接逻辑(原代码会出现重复域名)
base_url = "https://www.mecca.com"
productlinks = []

for x in range(1,5):
    soup = BeautifulSoup(requests.get(f'{base_url}/en-au/skincare/?page={x}', headers=headers).content, "html.parser")
    products = soup.find_all('div', class_="css-1r7iqog")
    for item in products:
        link = item.find('a', href=True)
        if link:
            productlinks.append(base_url + link['href'])

2. 使用语义化属性定位元素

放弃依赖动态CSS类,改用网站提供的data-testid属性定位,这类属性更稳定:

product_data = []
for link in productlinks:
    response = requests.get(link, headers=headers)
    soup = BeautifulSoup(response.content, "html.parser")
    
    # 提取品牌和名称
    title_area = soup.find('div', {'data-testid': 'product-title'})
    brand = title_area.find('span', {'data-testid': 'product-brand'}).text.strip() if title_area else '未获取到品牌'
    name = title_area.find('span', {'data-testid': 'product-name'}).text.strip() if title_area else '未获取到名称'
    
    # 提取成分
    ingredients = '未获取到成分'
    ingredient_area = soup.find('div', {'data-testid': 'ingredients'})
    if ingredient_area:
        ingredient_text = ingredient_area.find('p')
        if ingredient_text:
            ingredients = ingredient_text.text.strip()
    
    product_data.append({
        '品牌': brand,
        '产品名称': name,
        '成分': ingredients
    })

# 打印结果
for item in product_data:
    print(f"品牌: {item['品牌']}\n名称: {item['产品名称']}\n成分: {item['成分']}\n---")

3. 处理动态加载内容(备选方案)

如果上述方法仍无法获取内容,使用Selenium模拟浏览器渲染页面:

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
import time

driver = webdriver.Chrome()
product_data = []

for link in productlinks:
    driver.get(link)
    time.sleep(1)  # 给页面加载留缓冲时间
    try:
        # 等待成分区域加载完成
        WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, '[data-testid="ingredients"] p'))
        )
        
        brand = driver.find_element(By.CSS_SELECTOR, '[data-testid="product-brand"]').text.strip()
        name = driver.find_element(By.CSS_SELECTOR, '[data-testid="product-name"]').text.strip()
        ingredients = driver.find_element(By.CSS_SELECTOR, '[data-testid="ingredients"] p').text.strip()
        
        product_data.append({
            '品牌': brand,
            '产品名称': name,
            '成分': ingredients
        })
    except Exception as e:
        print(f"处理链接 {link} 时出错: {str(e)}")
        continue

driver.quit()
# 打印结果
for item in product_data:
    print(f"品牌: {item['品牌']}\n名称: {item['产品名称']}\n成分: {item['成分']}\n---")

注意事项

  • 添加请求间隔:在循环中加入time.sleep(1),避免短时间内发送大量请求触发反爬。
  • 定期检查定位器:网站可能更新页面结构,若后续出错需重新确认data-testid属性或元素层级。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 08:36:04