如何从CSS样式表中爬取目标数据?以提取background-image的URL为例
针对CSS内嵌/外联样式表中数据的爬取方案
可爬性说明
只要目标样式资源是浏览器公开可访问、未设置权限校验,且符合对应站点
robots.txt爬取规则的前提下,这类存放在CSS中的数据完全可以正常提取。
具体操作方法
根据站点技术实现的不同,可选择两种主流方案:
方案1:静态解析HTML+CSS(适配静态站点、CSS无动态生成的场景)
- 第一步:请求目标页面HTML源码,分别提取两类样式资源:页面内嵌
<style>标签的内容、<link rel="stylesheet">标签指向的外联样式表URL,单独请求所有外联CSS文件获取完整样式内容。 - 第二步:使用CSS解析库(如Python生态的
cssutils、Node.js生态的css模块)解析所有获取到的样式内容,匹配目标选择器对应的样式规则,你示例中目标选择器为.bgimage。 - 第三步:从匹配到的规则中提取目标属性值,示例中为
background-image属性,通过正则提取url()括号内的资源路径,补全为绝对路径即可得到可用的资源URL。
示例代码(Python):
import requests from lxml import etree import cssutils import re # 替换为实际目标页面URL TARGET_URL = "https://example.com/目标页面" # 请求页面HTML page_resp = requests.get(TARGET_URL) html_dom = etree.HTML(page_resp.text) # 收集所有CSS内容 all_css = [] # 提取内嵌style内容 inline_styles = html_dom.xpath('//style/text()') all_css.extend(inline_styles) # 提取并请求外联CSS ext_css_links = html_dom.xpath('//link[@rel="stylesheet"]/@href') for link in ext_css_links: # 补全相对路径为绝对路径 absolute_link = requests.compat.urljoin(TARGET_URL, link) css_resp = requests.get(absolute_link) all_css.append(css_resp.text) # 解析CSS提取目标图片URL for css_content in all_css: css_sheet = cssutils.parseString(css_content) for rule in css_sheet: # 过滤非样式规则 if rule.type != rule.STYLE_RULE: continue if '.bgimage' in rule.selectorText: bg_img_value = rule.style.getPropertyValue('background-image') # 提取url括号内的路径,去除多余引号 img_path = re.search(r'url\((.*?)\)', bg_img_value).group(1).strip('"\'') img_url = requests.compat.urljoin(TARGET_URL, img_path) print(f"提取到的图片地址:{img_url}")
方案2:无头浏览器渲染提取(适配CSS由JS动态生成的场景)
如果站点样式是前端JS动态生成插入的,静态解析无法拿到完整CSS,可以直接用Playwright、Puppeteer、Selenium这类无头浏览器工具加载完整页面,直接读取元素计算样式即可:
- 启动无头浏览器加载目标页面,等待页面所有资源加载、JS执行完成
- 调用浏览器内置API获取目标元素的计算样式,直接提取
background-image属性值 - 正则提取资源路径并补全为绝对路径即可
示例代码(Python Playwright):
from playwright.sync_api import sync_playwright import re import requests # 替换为实际目标页面URL TARGET_URL = "https://example.com/目标页面" with sync_playwright() as p: # 启动无头Chromium browser = p.chromium.launch(headless=True) page = browser.new_page() page.goto(TARGET_URL, wait_until="networkidle") # 读取元素计算样式 bg_img_value = page.eval_on_selector(".bgimage", "el => window.getComputedStyle(el).backgroundImage") # 提取图片路径 img_path = re.search(r'url\((.*?)\)', bg_img_value).group(1).strip('"\'') img_url = requests.compat.urljoin(TARGET_URL, img_path) if not img_path.startswith('http') else img_path print(f"提取到的图片地址:{img_url}") browser.close()
内容的提问来源于stack exchange,提问作者user17087759
相关产品推荐
相关产品推荐

