
本文介绍如何利用 requests + 正则表达式从动态渲染的房产页面中可靠提取 floorplan 图片链接,重点解决因 json 数据嵌套在 html 源码中导致的匹配失败问题,并提供健壮、可扩展的提取方案。
本文介绍如何利用 requests + 正则表达式从动态渲染的房产页面中可靠提取 floorplan 图片链接,重点解决因 json 数据嵌套在 html 源码中导致的匹配失败问题,并提供健壮、可扩展的提取方案。
在现代单页应用(SPA)或服务端渲染(SSR)的房产平台(如 Livabl)中,楼层平面图(floorplans)的图片链接通常不以标准 <img> 标签形式存在,而是作为 JSON 数据内联在 HTML 的 <script></script> 或文本节点中——例如嵌套在类似 "images": ["https://...", "..."] 的结构里。直接使用 BeautifulSoup 解析 DOM 往往无效,因为目标数据不在可见标签中;而简单 re.search() 又容易因上下文边界模糊、转义复杂或存在多组匹配而漏取(如原代码仅捕获首个匹配,但页面实际含 11 组 floorplan 数据)。
正确的策略是:定位所有符合 "images":[...] 模式的 JSON 数组片段,并逐个解析。关键在于:
- 使用
re.finditer()替代re.search(),确保捕获全部匹配项; - 正则需兼顾引号转义与数组闭合,推荐模式:
r'"images"s*:s*([[^]]*])'(更健壮,避免依赖反斜杠转义); - 提取后对 JSON 字符串调用
json.loads(),确保链接格式规范、无多余空格或转义错误。
以下是优化后的完整实现:
import re
import json
import requests
link = 'https://www.livabl.com/abbotsford-bc/jem1'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
'Referer': 'https://www.livabl.com/',
}
def get_floor_plan_images(url, headers):
res = requests.get(url, headers=headers, timeout=10)
res.raise_for_status() # 显式抛出网络异常
# 更鲁棒的正则:匹配 "images": [...](支持空格、换行、常见转义)
pattern = r'"images"s*:s*([[^]]*?])'
image_groups = []
for match in re.finditer(pattern, res.text):
try:
# 安全加载 JSON 数组(自动处理引号转义)
img_list = json.loads(match.group(1))
if isinstance(img_list, list):
image_groups.extend([url.strip() for url in img_list if isinstance(url, str) and url.strip()])
except (json.JSONDecodeError, ValueError):
continue # 跳过格式异常的片段
return image_groups
# 执行提取
images = get_floor_plan_images(link, headers)
print(f"成功提取 {len(images)} 张 floorplan 图片链接:")
for i, img_url in enumerate(images, 1):
print(f"{i:2d}. {img_url}")
✅ 注意事项与最佳实践:
-
避免硬编码转义:原始正则
r"{\"images\":(.*?]),"严重依赖反斜杠转义,极易因源码实际转义方式变化(如"或无转义)而失效;改用双引号+空白符容忍的模式更稳定。 -
验证响应内容:添加
res.raise_for_status()和timeout,防止静默失败。 -
防御性解析:
json.loads()可能抛异常,务必try/except;同时过滤空字符串和非字符串项,提升健壮性。 -
去重与去噪:若需唯一链接,可在返回前加
list(dict.fromkeys(images));若链接含相对路径,需结合urllib.parse.urljoin()补全。
该方法已验证可稳定提取 Livabl 页面中全部 11 张 floorplan 图片链接,适用于同类 JavaScript 注入 JSON 数据的场景,无需 Selenium,轻量高效。










