iT邦幫忙

0

Nodejs在heroku伺服器上運行讀取氣象局資料會有部分亂碼

如何解決氣象局部分資料亂碼呀?

https://ithelp.ithome.com.tw/upload/images/20190908/20110934cDkkPLnWHG.jpg
請教各位大大這個問題該如何解決?

補充:
https://ithelp.ithome.com.tw/upload/images/20190908/20110934pA5mvPpXPa.jpg
直接抓氣象局資料就會出現,但氣象局上的公開資料顯示卻正常。
https://ithelp.ithome.com.tw/upload/images/20190908/20110934JAeb5KBEAG.jpg

看更多先前的討論...收起先前的討論...
dragonH iT邦大師 1 級 ‧ 2019-09-08 16:20:05 檢舉
所以我說資料長怎樣呢

看是抓回來資料時就有這問題

還是秀出來才這樣
Huiicat iT邦新手 5 級 ‧ 2019-09-08 16:28:44 檢舉
感謝你的回答!我補充了圖片,感覺是抓回資料的時候就出錯了!
dragonH iT邦大師 1 級 ‧ 2019-09-08 16:41:17 檢舉
如果可以

建議貼個 url 讓我測
小魚 iT邦大師 1 級 ‧ 2019-09-08 18:26:36 檢舉
看起來好像需要註冊會員才能用.
Huiicat iT邦新手 5 級 ‧ 2019-09-08 19:41:18 檢舉
是啊,它需要授權碼才可以使用這樣…

2 個回答

0
小魚
iT邦大師 1 級 ‧ 2019-09-08 18:50:06

氣象局的資料看起來沒問題,
也許你可以考慮從編碼著手.

Huiicat iT邦新手 5 級 ‧ 2019-09-08 19:42:18 檢舉

試過encode和decode轉成big5或utf8都沒有改善,所以才想來問問有沒有人有類似的問題@@

小魚 iT邦大師 1 級 ‧ 2019-09-08 21:33:12 檢舉

Unicode呢?

2
dragonH
iT邦大師 1 級 ‧ 2019-09-08 20:39:30

https://ithelp.ithome.com.tw/upload/images/20190908/20117259pNJiRBfeTQ.png

實測

沒遇到此問題

所以你是用什麼 lib 去抓資料的呢?

request? axios?

用 request 也是沒什麼問題

https://ithelp.ithome.com.tw/upload/images/20190908/20117259OGEw3Lx5fQ.png

看更多先前的回應...收起先前的回應...
ccutmis iT邦高手 9 級 ‧ 2019-09-08 21:39:53 檢舉

管它是三個狗皮貼還是三支雨傘
我差點又想建議樓主用RegExp直接抓值了...
/images/emoticon/emoticon77.gif

Huiicat iT邦新手 5 級 ‧ 2019-09-08 21:45:58 檢舉

是用https.get抓取的,可是時好時壞,有時候會部分亂碼,有時候又會沒事><

Huiicat iT邦新手 5 級 ‧ 2019-09-08 21:46:20 檢舉
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);
        });

    })
dragonH iT邦大師 1 級 ‧ 2019-09-08 22:35:24 檢舉

ccutmis

regexp 這次應該就不管用了XD /images/emoticon/emoticon07.gif

dragonH iT邦大師 1 級 ‧ 2019-09-08 22:37:21 檢舉

Huiicat

可是我用

axios

request

https

抓都沒有這問題餒

丟到 heroku 也都正常

全部都是用預設的設定

heroku

另外

沒特別需求的話

會建議你用 axios

dragonH iT邦大師 1 級 ‧ 2019-09-08 22:42:13 檢舉

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}`);
})
Huiicat iT邦新手 5 級 ‧ 2019-09-08 22:45:09 檢舉

他是有時候會出現亂碼,我剛剛也是重新run一次一樣的程式碼,結果沒有亂碼(>_<)

但是就是有時候會出現,明天可能又會有,想抓出為甚麼會這樣

dragonH iT邦大師 1 級 ‧ 2019-09-08 22:57:59 檢舉

如果是 utf8 的問題

應該不會只有這幾個字有問題

沒遇到我也不知道怎麼解決 /images/emoticon/emoticon11.gif

搞不好也有可能是氣象局的問題

Huiicat iT邦新手 5 級 ‧ 2019-09-08 23:04:16 檢舉

我明天再測測看,如果確定是氣象局會在回來po
不過上網看,說是有可能是dom端口問題

dragonH iT邦大師 1 級 ‧ 2019-09-08 23:09:32 檢舉

/images/emoticon/emoticon12.gif

ccutmis iT邦高手 9 級 ‧ 2019-09-09 10:05:21 檢舉

dragonH

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%'));

/images/emoticon/emoticon82.gif

dragonH iT邦大師 1 級 ‧ 2019-09-09 10:24:44 檢舉

如果可以檢查是不是繁體字

e.g. charCodeAt(xx)

是亂碼才轉就更完美了XD /images/emoticon/emoticon07.gif

我是發問者朋友,今天早上測試又出現亂碼,不過確認氣象局資料是正常的(下面附上)。他的亂碼不一定是在相對溼度上而是其他都有可能突然變亂碼。會再綜合大家的意見改寫看看。/images/emoticon/emoticon41.gif

 "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"
          }
         },
dragonH iT邦大師 1 級 ‧ 2019-09-09 10:41:46 檢舉

那就換用 axios 吧

看看會不會改善

code 也會比較簡潔


看起來應該是 https 的鍋沒錯

我剛看了我昨天寫的

/with-https

也有這問題

/with-axios

/with-request 都正常

懶的解決的話

換 lib 應該是最快的

fillano iT邦超人 1 級 ‧ 2019-09-09 13:55:16 檢舉

不知道是不是伺服器處理chuck有缺陷,結果concat起來出問題XD

dragonH iT邦大師 1 級 ‧ 2019-09-09 14:23:47 檢舉

這就不知道了XD

打算晚點照這篇說的來試試看

不過我還是傾向 axios 那類的 lib 就是/images/emoticon/emoticon01.gif

自己 concat 太麻煩了

Huiicat iT邦新手 5 級 ‧ 2019-09-10 03:35:18 檢舉

試了bufferhelper仍然會有亂碼
https://ithelp.ithome.com.tw/upload/images/20190910/20110934Vw0hk4xYkI.jpg

Huiicat iT邦新手 5 級 ‧ 2019-09-10 03:36:59 檢舉

目前的程式碼,明天再換其他的方式

 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);
        });

    })
dragonH iT邦大師 1 級 ‧ 2019-09-10 09:18:15 檢舉

有什麼原因一定要用 https 嗎 XD /images/emoticon/emoticon11.gif

Huiicat iT邦新手 5 級 ‧ 2019-09-10 19:08:30 檢舉

想說試一下,以後或許會需要?
今天確認用buffer沒有亂碼,昨天看的亂碼也不見了。

dragonH iT邦大師 1 級 ‧ 2019-09-10 19:13:18 檢舉

如果是只做一般串接 api 這種

應該 axios 那類的 lib 就綽綽有餘

我是還沒遇過有什麼一定要用 https module 的情況啦XD

會一直推 axios 的原因是因為

1 .

他是 base on promise

2 .

前後端都能使用

我要發表回答

立即登入回答