氣象局的資料看起來沒問題,
也許你可以考慮從編碼著手.
實測
沒遇到此問題
所以你是用什麼 lib 去抓資料的呢?
request? axios?
用 request 也是沒什麼問題
管它是三個狗皮貼還是三支雨傘
我差點又想建議樓主用RegExp直接抓值了...
是用https.get抓取的,可是時好時壞,有時候會部分亂碼,有時候又會沒事><
return new Promise((resolve, reject) => {
https.get(weather_url, function (res) {
res.on('data', function (chunk) {
body += chunk;
});
res.on('end', function () {
datawe = JSON.parse(body);
// console.log(location);
resolve(datawe);
});
}).on('error', function (e) {
console.log("Got an error: ", e);
});
})
regexp 這次應該就不管用了XD
code
const Koa = require('koa');
const Router = require('koa-router');
const request = require('request');
const axios = require('axios').default;
const https = require('https');
const url = 'https://opendata.cwb.gov.tw/api/v1/rest/datastore/F-D0047-005?Authorization=';
const config = require('./config');
const app = new Koa();
const router = new Router();
const port = process.env.PORT || 5000;
router.get('/with-axios', async (ctx) => {
try {
const weatherDatas = await axios.get(`${url}${config.apiToken}`)
.then(res => res.data);
const datasToShow = weatherDatas.records.locations[0].location[0].weatherElement[6].time;
ctx.status = 200;
ctx.body = {
data: datasToShow,
}
} catch (err) {
ctx.throw(500, err);
}
});
router.get('/with-request', async (ctx) => {
const data = await getDataWithRequest();
ctx.status = 200;
ctx.body = {
data,
}
});
router.get('/with-https', async (ctx) => {
const data = await getDataWithHttps();
ctx.status = 200;
ctx.body = {
data: data.records.locations[0].location[0].weatherElement[6].time,
}
});
const getDataWithRequest = () => {
return new Promise((resolve, reject) => {
try {
request.get(`${url}${config.apiToken}`, (e, res, body) => {
if (e) {
reject(e);
return;
}
const weatherDatas = JSON.parse(body);
const datasToShow = weatherDatas.records.locations[0].location[0].weatherElement[6].time;
resolve(datasToShow);
});
} catch (err) {
reject(err);
}
});
};
const getDataWithHttps = () => {
return new Promise((resolve, reject) => {
try {
let body = '';
https.get(`${url}${config.apiToken}`, (res) => {
res.on('data', (chunk) => {
body += chunk;
});
res.on('end', () => {
resolve(JSON.parse(body));
});
});
} catch (err) {
reject(err);
}
});
}
app.use(async (ctx, next) => {
await next();
if (ctx.status === 404) {
ctx.body = 'route not found, try /with-axios, /with-request or /with-https';
} else {
console.log(ctx.status);
}
});
app.use(router.routes());
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
})
他是有時候會出現亂碼,我剛剛也是重新run一次一樣的程式碼,結果沒有亂碼(>_<)
但是就是有時候會出現,明天可能又會有,想抓出為甚麼會這樣
如果是 utf8 的問題
應該不會只有這幾個字有問題
沒遇到我也不知道怎麼解決
搞不好也有可能是氣象局的問題
我明天再測測看,如果確定是氣象局會在回來po
不過上網看,說是有可能是dom端口問題
const tmp_string=
'晴時多雲。溫度攝氏26至33度。舒適至悶熱。東北風 風速2級(每秒3公尺)。相???溼度74%';
console.log('原始資料:\n'+tmp_string);
console.log(tmp_string.replace(/([^。]+)。[^\d]+(\d{2})[^\d]+(\d{2})[^。]+。([^。]+)。([^。]+)。[^\d]+(\d{2})%/,'\n用RegExp篩選出有用的值:\n$1 $2 $3 $4 $5 $6'));
console.log(tmp_string.replace(/([^。]+)。[^\d]+(\d{2})[^\d]+(\d{2})[^。]+。([^。]+)。([^。]+)。[^\d]+(\d{2})%/,'\n用RegExp篩選後加上編排:\n$1。溫度攝氏$2至$3度。$4。$5。相對溼度$6%'));
如果都是只有固定某個字會變亂碼(例如 相???溼度) 那就更簡單了
const tmp_string=
'晴時多雲。溫度攝氏26至33度。舒適至悶熱。東北風 風速2級(每秒3公尺)。相???溼度74%';
console.log('原始資料:\n'+tmp_string);
console.log(tmp_string.replace(/([^。]+。[^\d]+\d{2}[^\d]+\d{2}[^。]+。[^。]+。[^。]+)。[^\d]+(\d{2})%/,'\n用RegExp篩選後加上編排:\n$1。相對溼度$2%'));
如果可以檢查是不是繁體字
e.g. charCodeAt(xx)
是亂碼才轉就更完美了XD
我是發問者朋友,今天早上測試又出現亂碼,不過確認氣象局資料是正常的(下面附上)。他的亂碼不一定是在相對溼度上而是其他都有可能突然變亂碼。會再綜合大家的意見改寫看看。
"elementName": "WeatherDescription",
"description": "天氣預報綜合描述",
"time": [
{
"startTime": "2019-09-09T06:00:00+08:00",
"endTime": "2019-09-09T18:00:00+08:00",
"elementValue": {
"value": "晴時多雲。降雨機率 0%。溫度攝氏26至32度。舒適至悶熱。偏南風 風速3級(每秒5公尺)。相對濕度76%。",
"measures": "NA"
}
},
那就換用 axios 吧
看看會不會改善
code 也會比較簡潔
看起來應該是 https 的鍋沒錯
我剛看了我昨天寫的
也有這問題
跟
/with-request 都正常
懶的解決的話
換 lib 應該是最快的
不知道是不是伺服器處理chuck有缺陷,結果concat起來出問題XD
試了bufferhelper仍然會有亂碼
目前的程式碼,明天再換其他的方式
return new Promise((resolve, reject) => {
https.get(weather_url, function (res) {
var bufferHelper = new BufferHelper();
res.on('data', function (chunk) {
bufferHelper.concat(chunk);
});
res.on('end', function () {
datawe = bufferHelper.toBuffer().toString();
datawe = JSON.parse(datawe);
resolve(datawe);
});
}).on('error', function (e) {
console.log("Got an error: ", e);
});
})