如何在自有站点集成Google Project Sunroof并实现地址同步交互
Google Project Sunroof 地址集成解决方案
方案一:无头浏览器自动化(推荐)
由于官方无公开API,可通过无头浏览器模拟用户操作实现地址填充、结果抓取,再通过后端接口将数据返回给你的前端页面。
步骤1:后端实现(Node.js + Puppeteer)
- 依赖安装:
npm install puppeteer express cors
- 核心代码示例:
const express = require('express'); const puppeteer = require('puppeteer'); const cors = require('cors'); const app = express(); app.use(cors()); app.use(express.json()); app.post('/get-sunroof-data', async (req, res) => { const { address } = req.body; if (!address) return res.status(400).send('地址不能为空'); let browser; try { browser = await puppeteer.launch({ headless: 'new', args: ['--no-sandbox'] }); const page = await browser.newPage(); await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'); await page.goto('https://sunroof.withgoogle.com', { waitUntil: 'networkidle2' }); // 填充地址并提交 await page.type('input[placeholder="Enter address"]', address); await page.click('button[type="submit"]'); await page.waitForNavigation({ waitUntil: 'networkidle2' }); // 提取关键数据(示例,需根据页面结构调整选择器) const roofStats = await page.evaluate(() => { return { usableArea: document.querySelector('.usable-roof-area')?.textContent, annualSavings: document.querySelector('.annual-savings')?.textContent, solarPotential: document.querySelector('.solar-potential')?.textContent }; }); res.json(roofStats); } catch (err) { console.error(err); res.status(500).send('获取数据失败,请检查地址或稍后重试'); } finally { if (browser) await browser.close(); } }); app.listen(3000, () => console.log('服务启动在端口3000'));
步骤2:前端对接
在你的表单页面添加提交逻辑,调用后端接口并展示结果:
document.getElementById('address-form').addEventListener('submit', async (e) => { e.preventDefault(); const address = document.getElementById('street-address').value; const response = await fetch('http://localhost:3000/get-sunroof-data', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ address }) }); const data = await response.json(); // 在弹窗中展示结果 const resultModal = document.getElementById('result-modal'); resultModal.innerHTML = ` <h3>太阳能潜力分析</h3> <p>可用屋顶面积:${data.usableArea || '暂无数据'}</p> <p>年节省电费:${data.annualSavings || '暂无数据'}</p> <p>太阳能潜力:${data.solarPotential || '暂无数据'}</p> `; resultModal.style.display = 'block'; });
方案二:反向代理+iframe嵌入(解决嵌入失败问题)
如果之前iframe嵌入失败是因为目标站的X-Frame-Options限制,可通过后端代理绕过:
- 后端代理配置(Express示例):
const express = require('express'); const request = require('request'); const app = express(); app.get('/proxy-sunroof', (req, res) => { const url = 'https://sunroof.withgoogle.com' + req.url; req.pipe(request(url)).pipe(res); }); app.listen(3000);
- 前端嵌入并通信:
<iframe id="sunroof-iframe" src="http://localhost:3000/proxy-sunroof" width="100%" height="800px"></iframe> <script> // 当用户提交表单时,向iframe发送地址数据 document.getElementById('address-form').addEventListener('submit', (e) => { e.preventDefault(); const address = document.getElementById('street-address').value; document.getElementById('sunroof-iframe').contentWindow.postMessage({ address }, '*'); }); // 在iframe加载的页面中添加监听(需修改代理后的页面,或通过注入脚本实现) // 注:此部分需通过Puppeteer或页面注入脚本完成,监听postMessage并填充地址 </script>
关键注意事项
- 遵守Google服务条款,控制请求频率,避免触发反爬机制,可添加请求间隔、IP轮换等策略
- 页面选择器可能随Sunroof更新变化,需定期检查调整
- 地址格式标准化:可在前端添加地址校验,确保输入符合规范(如包含街道、城市、邮编)
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

