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

使用BeautifulSoup4获取img标签src返回空数组问题求助

问题背景

需要从如下HTML片段中提取img标签的src链接地址:

<a href="https://i.sstatic.net/SvJzr.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/SvJzr.png" alt="enter image description here" /></a>

实际编写代码抓取目标站点的公司logo链接时,所有查找结果均返回空数组[],BeautifulSoup4似乎无法读取class为lazyload-wrapper的div标签内部的内容,原实现代码如下:

from urllib.request import Request
from bs4 import BeautifulSoup
from urllib.request import Request, urlopen

url = 'https://growjo.com/industry/Cannabis'
request = Request(
    url,
    headers={'User-Agent': 'Mozilla/5.0'}
)
page = urlopen(request)
page_content_bytes = page.read()
page_html = page_content_bytes.decode("utf-8")

soup = BeautifulSoup(page_html, "html.parser")

company_rows = soup.find_all("table",{"class":"jss31"})[0].find_all("tbody")[0].find_all("tr")

for company in company_rows:
    company_data = company.find_all("td")
    logo = company_data[1].find_all("div",{"class":"lazyload-wrapper"})[0].find_all("a")
    name = company_data[1].text
    print(logo)
    break
问题原因
  • 代码里用来定位表格的jss31是CSS-in-JS生成的动态类名,这类类名会随版本发布、页面渲染状态变化随机变更,不是稳定的元素定位标识
  • 目标站点的公司列表、logo内容是前端JavaScript动态渲染的,urllib只能拿到页面初始的静态HTML骨架,JS执行完成后才会往lazyload-wrapper节点里填充a、img等内容,静态HTML中这部分节点本身就是空的,自然无法通过BeautifulSoup解析到
  • 站点对logo做了懒加载处理,就算JS渲染完成,初始状态下img标签的src属性也可能是占位图,真实logo地址一般存放在data-src、data-lazy这类自定义属性中,等图片滚动到可视区域才会替换到src上
解决方案

方案1:使用支持JS渲染的抓取工具

替换urllib为可驱动浏览器执行页面JS的工具,等页面完全渲染、接口数据加载完成后再解析DOM,以Playwright为例的实现代码:

from playwright.sync_api import sync_playwright
from bs4 import BeautifulSoup

with sync_playwright() as p:
    # 启动无头浏览器
    browser = p.chromium.launch(headless=True)
    page = browser.new_page(user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36')
    page.goto('https://growjo.com/industry/Cannabis', wait_until='networkidle')
    # 等待表格行加载完成
    page.wait_for_selector('table tbody tr')
    page_html = page.content()
    browser.close()

soup = BeautifulSoup(page_html, "html.parser")
# 避开动态类名,直接通过标签结构定位表格行
company_rows = soup.select("table tbody tr")
for company in company_rows:
    company_data = company.find_all("td")
    if len(company_data) < 2:
        continue
    logo_wrapper = company_data[1].select_one(".lazyload-wrapper")
    if not logo_wrapper:
        continue
    logo_img = logo_wrapper.find("img")
    # 优先读取懒加载属性,再读默认src
    logo_url = logo_img.get("data-src", logo_img.get("src"))
    company_name = company_data[1].text.strip()
    print(company_name, logo_url)
    break

方案2:直接调用站点数据接口

打开浏览器开发者工具,切换到网络面板筛选XHR/Fetch请求,可以找到页面加载时拉取公司列表的后端接口,接口返回的是结构化JSON数据,直接包含logo地址、公司名称等字段,不需要解析HTML,抓取效率更高,也不会被前端渲染逻辑影响。

注意事项
  • 定位页面元素时不要使用jss、css-开头的动态类名,这类类名随时可能变化,优先使用固定id、角色属性、稳定的标签层级结构做定位
  • 解析懒加载图片时,不要只读取src属性,注意检查元素上的自定义懒加载属性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 06:15:36