如何从script标签引入的外部JS文件中提取餐厅名称、经纬度信息
Grab菲律宾餐厅数据爬取方案
核心思路
该站点为Next.js服务端渲染+客户端异步加载的架构,打包后的JS文件经过混淆压缩,直接从JS源码找变量效率极低,优先走抓异步请求的方案:
- 每次点击「Load More」按钮时,站点会向后端发起请求拉取8条新的餐厅数据,直接复用该接口即可批量获取全量数据,无需模拟点击操作。
具体操作步骤
- 打开浏览器F12开发者工具,切换到「网络」标签,筛选
Fetch/XHR类型的请求 - 点击页面上的「Load More」按钮,找到新出现的餐厅列表请求,查看该请求的:
- 请求URL
- 请求方法(一般为GET/POST)
- 请求头必填字段(如
User-Agent、Cookie、站点专属的校验头如x-grab-webuid等) - 请求参数(会包含偏移量
offset,每次加载加8即可拉取下一页数据,还有你当前定位的经纬度、城市编码等固定参数)
- 返回的响应为标准JSON格式,直接从
searchResult/restaurants字段下提取每个餐厅的name(名称)、latitude(纬度)、longitude(经度)字段即可。
最简JS实现代码(Node.js环境)
const fs = require('fs'); const axios = require('axios'); // 运行前先执行npm i axios安装依赖 // 以下参数请替换成你从开发者工具里抓到的实际值 const BASE_URL = '你抓到的餐厅列表接口地址'; const HEADERS = { 'User-Agent': '你浏览器的UA字符串', 'Cookie': '你当前页面的Cookie值', // 其他必填请求头按你抓到的内容补充 }; const TOTAL_COUNT = 100; // 你要爬的总餐厅数,可先抓一次请求看返回里的total字段填实际值 const CSV_HEADER = '餐厅名称,纬度,经度\n'; let csvContent = CSV_HEADER; async function fetchRestaurants() { for (let offset = 0; offset < TOTAL_COUNT; offset += 8) { console.log(`正在爬取第${offset+1}-${offset+8}条数据`); const res = await axios.get(BASE_URL, { headers: HEADERS, params: { // 其他固定请求参数按你抓到的内容填写 offset: offset, limit: 8 } }); // 以下解析逻辑按实际返回的JSON结构调整即可 const restaurantList = res.data.searchResult.restaurants; restaurantList.forEach(item => { const row = `"${item.name}",${item.latitude},${item.longitude}\n`; csvContent += row; }); // 加1秒间隔避免被站点封禁 await new Promise(resolve => setTimeout(resolve, 1000)); } fs.writeFileSync('grab_restaurants.csv', csvContent, 'utf8'); console.log('爬取完成,文件已保存为grab_restaurants.csv'); } fetchRestaurants();
注意事项
- 请求头缺失会大概率返回403拒绝访问,所有请求头请完全和浏览器发起的请求保持一致
- 不要短时间内发起大量请求,可适当拉长请求间隔避免IP被临时封禁
- 若需要动态获取Cookie,可使用Puppeteer模拟浏览器打开页面后自动提取请求头,无需手动复制
内容的提问来源于stack exchange,提问作者RPM
相关产品推荐
相关产品推荐

