如何使用Python提取HTML中图片的current source完整链接
在进行网页图片提取操作时,最初使用如下代码获取图片URL:
image = soup.findAll('img') image_link = image["src"]
运行后发现获取到的src属性值并非可直接访问、用于保存图片的完整链接,浏览器开发者工具元素面板中可见标注为current source的属性项,相关说明和提取方法如下:
current source的具体含义
开发者工具里标注的current source,对应img DOM元素的只读属性currentSrc,和标签上静态写入的src属性有本质区别:
- 静态HTML源码里写的
src属性很多时候是懒加载占位图、低质量预览缩略图、相对路径地址,并不是浏览器最终加载展示的真实图片地址 - 目前多数站点会配置响应式图片(通过
srcset/sizes属性)、JS懒加载逻辑,浏览器会根据当前设备分辨率、视口大小、滚动位置,自主选择适配的图片资源发起请求,currentSrc就是浏览器最终实际加载、渲染到页面上的图片对应的完整绝对URL,和你在页面上看到的图片资源完全对应。
原有代码的问题
最初的写法存在两个核心问题,直接导致拿不到正确的图片链接:
findAll('img')返回的是页面所有img标签组成的列表对象,不是单个标签元素,直接对列表调用["src"]取值会抛出类型错误,需要遍历列表逐个处理单个标签- BeautifulSoup仅能解析网页初始返回的静态HTML源码,不会执行页面内的JavaScript,也不会模拟浏览器的资源选择、加载逻辑:如果图片地址是JS动态注入、或者通过srcset规则匹配生成,静态解析src属性自然无法拿到最终的真实地址。
用Python提取currentSrc对应完整链接的方法
根据页面的渲染逻辑,可以选择两种适配方案:
方案1:适配静态页面(无JS懒加载、仅存在相对路径/响应式srcset配置)
这类场景不需要模拟浏览器运行,直接通过静态解析+路径拼接即可拿到正确链接,示例代码:
from bs4 import BeautifulSoup import requests from urllib.parse import urljoin target_url = "待爬取的目标网页地址" # 加上常规UA避免被基础反爬拦截 resp = requests.get(target_url, headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"}) soup = BeautifulSoup(resp.text, "html.parser") base_url = resp.url # 作为相对路径拼接的根地址 for img in soup.find_all("img"): real_img_link = "" # 优先解析srcset,取分辨率最高的资源(和浏览器默认选的最高优先级资源一致) if img.get("srcset"): srcset_items = [item.strip().split() for item in img["srcset"].split(",") if item.strip()] # 按图片宽度从大到小排序 srcset_items.sort(key=lambda x: int(x[1].rstrip("w")), reverse=True) real_img_link = urljoin(base_url, srcset_items[0][0]) elif img.get("src"): # 拼接相对路径为完整绝对路径 real_img_link = urljoin(base_url, img["src"]) if real_img_link: print(real_img_link)
方案2:适配JS动态渲染/懒加载页面
这类场景静态解析无法拿到JS执行后的最终属性,需要用可模拟浏览器运行的工具直接读取DOM的currentSrc属性,最简便的工具是Playwright,示例代码:
from playwright.sync_api import sync_playwright 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/120.0.0.0 Safari/537.36") # 等待页面网络空闲,确保初始资源加载完成 page.goto("待爬取的目标网页地址", wait_until="networkidle") # 滚动到页面底部,触发所有懒加载图片的加载逻辑 page.evaluate("window.scrollTo(0, document.body.scrollHeight)") page.wait_for_timeout(2000) # 预留2秒等待图片资源加载 # 直接读取所有img标签的currentSrc属性,和开发者工具看到的current source完全一致 img_links = page.eval_on_selector_all("img", "elements => elements.map(el => el.currentSrc)") # 过滤空值 img_links = [link for link in img_links if link] print(img_links) browser.close()
提示:如果目标站点有较强的反爬机制,可以对应给请求/浏览器实例添加代理、反检测参数,避免被拦截。

内容的提问来源于stack exchange,提问作者Fateme Nazari
相关产品推荐
相关产品推荐

