NodeJS请求Swiggy API遇403及无效JSON错误求助
问题:调用Swiggy API返回403并解析JSON失败
我是NodeJS新手,尝试使用以下代码从Swiggy在线API获取JSON响应:
// server.js const express = require('express'); const cors = require('cors'); const fetch = require('node-fetch'); const app = express(); const port = process.env.PORT || 3001; app.use(cors()); app.get('/api/data', async (req, res) => { try { const apiUrl = "https://www.swiggy.com/dapi/restaurants/list/v5?lat=28.6083697&lng=77.293112&page_type=DESKTOP_WEB_LISTING"; // Replace with the actual API URL const response = await fetch(apiUrl); const data = await response.json(); return res.json(data); } catch (error) { console.error('Error fetching data:', error); return res.status(500).json({ error: 'Internal Server Error' }); } }); app.listen(port, () => { console.log(`Server is running on port ${port}`); });
发起GET请求时,控制台出现如下错误:
Server is running on port 3001 Error fetching data: FetchError: invalid json response body at https://www.swiggy.com/dapi/restaurants/list/v5?lat=28.6083697&lng=77.293112&page_type=DESKTOP_WEB_LISTING reason: Unexpected token '<', "<html lang"... is not valid JSON at /home/priya/Documents/server/node_modules/node-fetch/lib/index.js:273:32 at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async /home/priya/Documents/server/index.js:15:18 { type: 'invalid-json' }
我尝试打印响应信息,结果如下:
Response { size: 0, timeout: 0, [Symbol(Body internals)]: { body: PassThrough { _events: [Object], _readableState: [ReadableState], _writableState: [WritableState], allowHalfOpen: true, _maxListeners: undefined, _eventsCount: 5, [Symbol(shapeMode)]: true, [Symbol(kCapture)]: false, [Symbol(kCallback)]: null }, disturbed: false, error: null }, [Symbol(Response internals)]: { url: 'https://www.swiggy.com/dapi/restaurants/list/v5?lat=28.6083697&lng=77.293112&page_type=DESKTOP_WEB_LISTING', status: 403, statusText: 'Forbidden', headers: Headers { [Symbol(map)]: [Object: null prototype] }, counter: 0 } }
解决方案
问题根源
- 403状态码说明Swiggy服务器拒绝了请求,默认
node-fetch发起的请求缺少浏览器标识的请求头,被服务器识别为非合法请求拦截。 - 解析JSON失败是因为403返回的是HTML错误页面,而非预期的JSON数据,因此解析时抛出"Unexpected token '<'"错误。
修改后的代码
// server.js const express = require('express'); const cors = require('cors'); const fetch = require('node-fetch'); const app = express(); const port = process.env.PORT || 3001; app.use(cors()); app.get('/api/data', async (req, res) => { try { const apiUrl = "https://www.swiggy.com/dapi/restaurants/list/v5?lat=28.6083697&lng=77.293112&page_type=DESKTOP_WEB_LISTING"; // 添加模拟浏览器的请求头,避免被拦截 const requestHeaders = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', 'Accept': 'application/json, text/plain, */*' }; const response = await fetch(apiUrl, { headers: requestHeaders }); // 先验证响应状态,再解析JSON if (!response.ok) { throw new Error(`请求失败,状态码:${response.status} ${response.statusText}`); } const data = await response.json(); return res.json(data); } catch (error) { console.error('获取数据失败:', error); return res.status(500).json({ error: error.message || '服务器内部错误' }); } }); app.listen(port, () => { console.log(`Server is running on port ${port}`); });
关键修改点
- 添加
User-Agent和Accept请求头,模拟浏览器的请求特征,绕过Swiggy的基础反爬拦截。 - 增加响应状态码校验,在解析JSON前先判断请求是否成功,避免无效解析抛出异常。
内容的提问来源于stack exchange,提问作者priya jha
相关产品推荐
相关产品推荐

