用 Agent 帮我买房:小区数据采集、测评图文生成全流程
我在苏州买房,需要对比十几个小区的成交价、配套、物业费......手动查数据一天都搞不定一个小区。后来我让 Agent 帮我干这活:爬数据、算评分、生成小红书图文,一套流程走下来,46 篇测评稿子全出来了。这篇文章完整记录这个实战过程------从踩坑到跑通,让你看完觉得"我也能这么用"。
一、背景:一个人买房的信息地狱
我在苏州买房,目标区域锁定后,候选小区有十几个。每个小区我需要知道:
- 挂牌价 & 成交价:历史成交趋势、最近成交单价
- 租金:租售比
- 物业费:持有成本
- 配套评分:学校、医院、地铁、商业
- 成交记录:最近成交的楼层、面积、单价
这些数据分散在房天下、贝壳、安居客等平台,手动一个个查,一个小区至少半小时。十几个小区就是一整天。而且数据格式不统一,没法直接对比。
更头疼的是:我还运营小红书号做房产测评,需要把数据整理成图文发布。一篇测评从查数据到出图文,手动搞至少 2 小时。
所以我的需求很明确:让 Agent 帮我自动化数据采集和图文生成。
二、整体架构:Agent 做了什么?
css
┌─────────────────────────────────────────────────────────┐
│ 用户输入小区名 │
└────────────────────────┬────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Agent 数据采集层 │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 挂牌价 │ │ 成交记录 │ │ 配套评分 │ │
│ │ 爬虫 │ │ 爬虫 │ │ 爬虫 │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ 数据源:房天下(fang.com) │
└────────────────────────┬────────────────────────────────┘
│ JSON 数据
▼
┌─────────────────────────────────────────────────────────┐
│ Agent 评分计算层 │
│ ┌──────────────────────────────────────────┐ │
│ │ 9 维评估体系 │ │
│ │ 价格 / 租售比 / 物业费 / 地段 / 教育 │ │
│ │ 医疗 / 交通 / 商业 / 成交价 │ │
│ └──────────────────────────────────────────┘ │
│ 输出:评分 + 各维度雷达图数据 │
└────────────────────────┬────────────────────────────────┘
│ 评分结果
▼
┌─────────────────────────────────────────────────────────┐
│ Agent 内容生成层 │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 测评文案 │ │ 雷达图 │ │ 信息卡片 │ │
│ │ 生成 │ │ Canvas │ │ PNG │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ 输出:小红书图文(文案 + 图片) │
└─────────────────────────────────────────────────────────┘
核心思路:数据采集 → 评分计算 → 内容生成,三步走,全链路 Agent 驱动。
三、第一步:数据采集------踩坑比写代码难
3.1 数据源选择
我试过四个平台:
| 平台 | 反爬难度 | 数据质量 | 可用性 |
|---|---|---|---|
| 房天下 | 低 | 挂牌价、租金、物业费、成交记录、配套全有 | ✅ 可用 |
| 贝壳 | 极高(接口加密+验证码) | 数据最全 | ❌ 放弃 |
| 安居客 | 高(字体反爬+接口签名) | 挂牌价+部分成交 | ❌ 放弃 |
| 好好选房 | 高(需登录+风控) | 成交数据不错 | ❌ 放弃 |
结论:只有房天下能稳定爬取。虽然数据不是最全的,但挂牌价、租金、物业费、成交记录、配套评分都有,够用了。
3.2 爬虫实现
后端用 Node.js + Express + Cheerio,核心逻辑很简单:
javascript
// 爬取小区详情页
async function fetchCommunityDetail(communityId) {
const url = `https://m.fang.com/esf/suzhou/${communityId}.html`;
const html = await cachedFetch(url);
const $ = cheerio.load(html);
return {
name: $('.community-name').text().trim(),
avgPrice: parsePrice($('.avg-price').text()),
rentPrice: parsePrice($('.rent-price').text()),
propFee: parseFloat($('.prop-fee').text()) || 0,
// ... 其他字段
};
}
// 爬取成交记录
async function fetchDealRecords(communityId) {
const url = `https://m.fang.com/esf/suzhou/${communityId}_deal.html`;
const html = await cachedFetch(url);
const $ = cheerio.load(html);
const records = [];
$('.deal-item').each((i, el) => {
records.push({
date: $(el).find('.deal-date').text(),
price: parsePrice($(el).find('.deal-price').text()),
area: $(el).find('.deal-area').text(),
floor: $(el).find('.deal-floor').text(),
});
});
return records;
}
3.3 踩坑:超时和缓存
坑 1 :Node.js 的 node-fetch v2 不支持 timeout 参数,设置 timeout: 15000 会被静默忽略,请求可能永远挂住。
解法 :用 AbortController + setTimeout 实现超时:
javascript
async function cachedFetch(url, timeoutMs = 15000) {
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), timeoutMs);
try {
const res = await fetch(url, { signal: controller.signal });
clearTimeout(timer);
return await res.text();
} finally {
clearTimeout(timer);
}
}
坑 2:同一小区多次请求会触发风控。解法是加内存缓存,采集一次后后续直接读缓存:
javascript
const cache = new Map();
async function cachedFetch(url) {
if (cache.has(url)) return cache.get(url);
const result = await fetchWithTimeout(url);
cache.set(url, result);
return result;
}
坑 3 :房天下移动端页面结构会变。解法:CSS 选择器不要太严格,用 .contains() 或模糊匹配兜底。
四、第二步:9 维评估体系------给房子打个分
光有数据不够,需要一个评分体系把数据变成可比较的结果。我设计了 9 个维度:
| 维度 | 数据来源 | 评分逻辑 |
|---|---|---|
| 价格 | 挂牌价 | 与同区域均价对比,越低越好 |
| 租售比 | 租金/挂牌价 | 年租金/总价,越高越好 |
| 物业费 | 物业费 | 与区域均值对比 |
| 地段 | 配套评分 | 综合打分 |
| 教育 | 附近学校 | 数量 × 质量 |
| 医疗 | 附近医院 | 数量 × 等级 |
| 交通 | 地铁/公交 | 距离 × 线路数 |
| 商业 | 商场/超市 | 数量 × 距离 |
| 成交价 | 最近成交记录 | 与挂牌价偏差 |
4.1 评分核心逻辑
javascript
function evaluate(data) {
const scores = {};
// 价格维度:与区域均价对比
const priceRatio = data.avgPrice / data.areaAvgPrice;
scores.price = priceRatio <= 0.9 ? 9 :
priceRatio <= 1.0 ? 7 :
priceRatio <= 1.1 ? 5 : 3;
// 租售比维度
const rentalYield = (data.rentPrice * 12) / (data.avgPrice * data.avgArea);
scores.rental = rentalYield >= 0.03 ? 9 :
rentalYield >= 0.02 ? 7 :
rentalYield >= 0.01 ? 5 : 3;
// 成交价维度:成交价 < 挂牌价越多,说明议价空间大
const dealDiscount = (data.avgPrice - data.avgDealPrice) / data.avgPrice;
scores.deal = dealDiscount >= 0.1 ? 9 :
dealDiscount >= 0.05 ? 7 : 5;
// ... 其他维度类似
const total = Object.values(scores).reduce((a, b) => a + b, 0);
const maxTotal = 9 * 9; // 9个维度,满分9分
return {
scores,
totalScore: total,
percentage: Math.round((total / maxTotal) * 100),
verdict: total >= 60 ? '值得买' : total >= 45 ? '一般' : '不建议',
};
}
4.2 踩坑:除零防御
坑 :有的小区没有成交记录,avgDealPrice 为 0,做除法就 NaN 了。
解法:每个维度计算前都要做防御:
javascript
function safeDivide(a, b, fallback = 0) {
return b === 0 ? fallback : a / b;
}
看起来很简单,但这种边界条件在实际数据中到处都是。没有成交记录、物业费为空、租金查不到......每种情况都要处理。
五、第三步:图文生成------从数据到小红书
5.1 文案生成
Agent 根据评分结果生成真人语气的测评文案:
diff
🏠 ****园 测评
📍 位置:苏州***
💰 挂牌均价:42,800 元/㎡
📊 综合评分:7.2/9(80%)
✅ 亮点:
- 地段评分 8/9,配套成熟
- 成交价低于挂牌价 8%,议价空间大
- 物业费 3.8 元/㎡,园区中档水平
⚠️ 注意:
- 租售比偏低(1.8%),投资回报一般
- 教育配套评分 5/9,学区一般
💡 结论:自住可考虑,投资需谨慎
踩坑:小红书文案必须用真人语气,不能有任何 AI 痕迹。早期版本文案太"工整",读者一眼看出是机器生成的。后来调整为更口语化、带个人观点的风格,效果好了很多。
5.2 图片生成
用微信小程序的 Canvas 画雷达图 + 信息卡片:
javascript
// 小程序端 Canvas 绘制雷达图
function drawRadarChart(ctx, data) {
const dimensions = ['价格', '租售比', '物业费', '地段', '教育', '医疗', '交通', '商业', '成交价'];
const cx = 150, cy = 150, maxR = 100;
// 画底图(9边形网格)
dimensions.forEach((_, i) => {
const angle = (Math.PI * 2 * i) / dimensions.length - Math.PI / 2;
// 画从中心到顶点的线
ctx.beginPath();
ctx.moveTo(cx, cy);
ctx.lineTo(cx + maxR * Math.cos(angle), cy + maxR * Math.sin(angle));
ctx.stroke();
});
// 画数据区域
ctx.beginPath();
dimensions.forEach((_, i) => {
const angle = (Math.PI * 2 * i) / dimensions.length - Math.PI / 2;
const r = (data[i] / 9) * maxR;
const x = cx + r * Math.cos(angle);
const y = cy + r * Math.sin(angle);
if (i === 0) ctx.moveTo(x, y);
else ctx.lineTo(x, y);
});
ctx.closePath();
ctx.fillStyle = 'rgba(54, 162, 235, 0.3)';
ctx.fill();
}
5.3 分享功能
测评结果支持分享给微信好友和朋友圈:
javascript
// result.js 分享逻辑
onShareAppMessage() {
return {
title: `${this.data.communityName} ${this.data.verdict} ${this.data.percentage}分`,
path: `/pages/result/result?data=${encodeURIComponent(JSON.stringify(this.data))}`,
};
},
onShareTimeline() {
return {
title: `${this.data.communityName} 房价测评:${this.data.verdict}`,
};
},
六、性能优化:让"生成图片"不再慢
用户反馈"图片生成有点慢"。根因是:点击"开始测评"时才去请求地段配套数据,API 请求 3-5 秒,用户在这期间干等。
解法:预取。在用户选择小区时,就提前把地段配套数据拉到内存缓存:
javascript
// 选择小区时预取
async function prefetchLocationData(communityId) {
const cached = locationCache.get(communityId);
if (cached) return cached;
const data = await fetchLocationData(communityId);
locationCache.set(communityId, data);
return data;
}
// 开始测评时直接读缓存
async function evaluate(communityId) {
const locationData = locationCache.get(communityId) || await fetchLocationData(communityId);
// ... 评分计算
}
效果:选择小区时无感预取,点测评按钮后 0 等待直接出图。
七、从工具到内容:46 篇测评的生产流水线
有了数据采集 + 评分 + 图文生成的全链路,生产测评内容就变成了流水线:
输入小区名 → 爬数据(5s)→ 算评分(<1s)→ 生成图文(3s)→ 发布小红书(手动)
单篇从 2 小时压缩到 10 秒(不含手动发布)。46 篇测评,如果手动搞要 90+ 小时,用 Agent 后实际生产时间不到 1 小时。
效果对比
| 指标 | 纯手动 | Agent 辅助 |
|---|---|---|
| 单篇耗时 | 2 小时 | 10 秒 |
| 数据准确度 | 依赖人工查抄 | 爬虫自动采集,数据源统一 |
| 评分一致性 | 主观判断,波动大 | 9 维体系,客观可比 |
| 46 篇总耗时 | ~90 小时 | < 1 小时 |
| 错误率 | 抄错/算错 | 除零防御+参数校验 |
八、踩坑总结:6 个实战经验
1. 数据源选最稳的,不是最全的
贝壳数据最全但反爬最严,花 3 天搞不定。房天下数据够用,1 天就跑通了。先跑通再优化。
2. 每个数值计算都做除零防御
真实数据处处是坑:没有成交记录的小区、物业费为空的小区、租金查不到的小区......每个 a / b 都要防 b === 0。
3. 小红书文案要真人语气
工整的报告没人看。口语化、带个人观点、有"踩"有"赞"的文案才有人互动。
4. 图片不要标注数据来源
早期图片上标注了"数据来源:好好选房",被平台判定为广告引流。后来去掉所有来源标注,只保留测评结论。
5. 预取比懒加载好
用户选择小区时预取数据,比点击后才加载体验好 10 倍。预取是消灭等待感的关键。
6. Agent 不替代决策,只提供信息
评分体系是客观工具,但买房决策还要考虑个人偏好(楼层、朝向、通勤距离等)。Agent 的价值是让你在信息充分的情况下做决策,而不是替你做决策。
九、下一步:把这个能力做成小程序
这个数据采集 + 评分的流程,我已经封装成微信小程序"房价测来测去",让任何人都能输入小区名、拿到 9 维评分。
小程序技术栈:
- 后端:Node.js + Express + Cheerio 爬虫
- 前端:微信小程序原生开发
- 评分引擎:纯 JS 实现,9 维评估体系
核心功能:输入价格 → 判断值不值 → 输出评分 + 雷达图 + 测评结论。
这就是 Agent 实战的价值:从一个真实需求出发,把重复劳动自动化,再把能力产品化。
十、总结
回顾这个实战项目,Agent 扮演了三个角色:
| 角色 | 做了什么 | 效果 |
|---|---|---|
| 数据采集员 | 爬取房天下数据 | 单小区 5 秒,替代手动 30 分钟 |
| 分析师 | 9 维评分计算 | 客观可比,替代主观判断 |
| 内容生成器 | 测评文案 + 雷达图 | 10 秒出稿,替代 2 小时手写 |
关键体会:
- Agent 的价值在于把人从重复劳动中解放出来,而不是替代人的判断
- 先跑通最小闭环,再优化细节------从 1 个小区到 46 篇,从脚本到小程序
- 数据采集的坑最多------选数据源、防反爬、做缓存、处理空值,每一步都是实战
- 内容生成要符合平台调性------小红书要真人语气,不要 AI 味
下一篇,我会分享"用 Agent 做小程序"的完整实战------从需求到代码,Agent 如何帮我把"房价测来测去"从想法变成产品。