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

使用BeautifulSoup提取无href的图片URL——Mecca护肤页爬取求助

爬取护肤产品图片URL遇到问题

我尝试爬取护肤品类页面的所有产品,提取每个产品的品牌、名称和图片URL,但在提取图片URL时卡住了——图片相关标签没有href属性。以某产品页面为例,图片的HTML结构如下:

<picture class="css-1azgcry-container" id="image-reponsive-container" data-testid="imageReponsiveContainer">  
  <img class="" title="Tatcha - Indigo Cleansing Balm" alt="Tatcha - Indigo   Cleansing Balm" src="https://www.mecca.com.au/on/demandware.static/-/Sites-mecca-online-catalog/default/dw0a0707d8/product/tatcha/hr/i-059912-indigo-cleansing-balm-7-1-940.jpg" data-testid="imageReponsiveImg">
</picture>

我需要提取<img>标签里src属性对应的URL,但下面的代码在提取图片URL部分存在问题,请帮忙修正:

import requests
from bs4 import BeautifulSoup

url = "https://www.mecca.com.au/skin-care/"
params = {"start": "0", "sz": "36", "format": "ajax"}
for params["start"] in range(0, 36 * 5, 36):
    productlinks = []
    cataloguelist = []
    soup = BeautifulSoup(requests.get('https://www.mecca.com.au/skin-care/', params=params).content, "html.parser")
    products = soup.find_all('div', class_="grid-product-info")

    for item in products:
        for link in item.find_all('a', href=True):
            productlinks.append(url + link['href'])

    for link in productlinks:
        response = requests.get(link)

        soup = BeautifulSoup(response.content, "html.parser")
        brand = soup.find('a', class_='css-1p371np-size5-size5-sansSerif-sansSerif-brandNameLink').text
        name = soup.find('span', class_='css-1noela6-paragraph-paragraph-sansSerif-sansSerif-productName').text
### 这里是我卡住的地方,我也试过用'picture'和class_='css-1azgcry-container'
        image = soup.find('picture', attrs={'css-1azgcry-container', 'img', 'alt', 'src'})
        
print(brand, name, image)

解决方案

你的问题出在图片提取的代码逻辑上:

  1. attrs={'css-1azgcry-container', 'img', 'alt', 'src'} 写法错误,attrs需要传入键值对(比如{'class': 'css-1azgcry-container'}),而不是集合。
  2. 你需要先找到<picture>标签,再定位里面的<img>元素,最后提取src属性;或者直接通过<img>的data-testid定位(更稳定,因为class可能随网站更新变化)。

修正后的图片提取代码

可以用两种方式实现:

# 方式1:通过picture标签的class定位,再找内部img
picture = soup.find('picture', class_='css-1azgcry-container')
image_url = picture.find('img')['src'] if picture and picture.find('img') else None

# 方式2:直接通过img的data-testid定位(推荐,属性更稳定)
img = soup.find('img', data-testid='imageReponsiveImg')
image_url = img['src'] if img else None

完整修正后的代码(含异常处理,避免单个产品提取失败导致程序中断)

import requests
from bs4 import BeautifulSoup

base_url = "https://www.mecca.com.au/skin-care/"
params = {"start": "0", "sz": "36", "format": "ajax"}
cataloguelist = []  # 移到循环外,避免每次重置

for params["start"] in range(0, 36 * 5, 36):
    productlinks = []
    response = requests.get(base_url, params=params)
    soup = BeautifulSoup(response.content, "html.parser")
    products = soup.find_all('div', class_="grid-product-info")

    for item in products:
        for link in item.find_all('a', href=True):
            # 拼接完整产品链接,避免重复添加base_url
            product_link = link['href'] if link['href'].startswith('http') else base_url + link['href']
            productlinks.append(product_link)

    for link in productlinks:
        try:
            response = requests.get(link)
            response.raise_for_status()  # 检查请求是否成功
            soup = BeautifulSoup(response.content, "html.parser")

            # 提取品牌
            brand_elem = soup.find('a', class_='css-1p371np-size5-size5-sansSerif-sansSerif-brandNameLink')
            brand = brand_elem.text.strip() if brand_elem else "未知品牌"

            # 提取产品名称
            name_elem = soup.find('span', class_='css-1noela6-paragraph-paragraph-sansSerif-sansSerif-productName')
            name = name_elem.text.strip() if name_elem else "未知名称"

            # 提取图片URL(推荐用data-testid定位)
            img_elem = soup.find('img', data-testid='imageReponsiveImg')
            image_url = img_elem['src'] if img_elem else "无图片URL"

            cataloguelist.append({
                "brand": brand,
                "name": name,
                "image_url": image_url
            })

            print(f"品牌:{brand},名称:{name},图片URL:{image_url}")
        except Exception as e:
            print(f"处理链接{link}时出错:{str(e)}")

# 可选:将结果保存到文件
# import json
# with open('mecca_skincare.json', 'w', encoding='utf-8') as f:
#     json.dump(cataloguelist, f, ensure_ascii=False, indent=2)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 08:10:56