iT邦幫忙

0

無法抓取JSON資料

小弟要抓取屏東縣政府的開放資料,但怎麼抓都沒辦法
網址:http://i-pingtung.com/OpenData/Attractions?start=100&limit=2000
[]http://ithelp.ithome.com.tw/upload/images/20170905/20106707JnRERya40f.png

timloo iT邦研究生 2 級 ‧ 2017-10-06 16:44:03 檢舉
我對vue.js 不熟,所以很納悶這個開發界面,怎麼沒秀錯誤訊息。
可以用一個簡單的jquery getJSON 試一下。

例如

<script>

$.getJSON( "http://i-pingtung.com/OpenData/Attractions?start=100&limit=2000", function( json ) {
console.log( "JSON Data: " + json );
});

</script>

然後用chrome的開發人員工具,看一下console的地方。

還是老問題,CORS.

Failed to load http://i-pingtung.com/OpenData/Attractions?start=100&limit=2000: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://192.168.0.21' is therefore not allowed access.

不知道該廠商是否可以更改一下 web server上的 設定。

例如,https://enable-cors.org/

各種web server 都可以設 支援 CORS.

目前,不支援的話, 可以google 一下 vue.js cors 或 Access-Control-Allow-Origin vue.js 這類的關鍵字 試一下。

之前網友有提到的桃機航班資訊,和屏東縣政府的景點搜尋,都有這問題,
讓open data 的傳播,少了一點便利性。
2
timloo
iT邦研究生 2 級 ‧ 2017-10-06 17:43:55
最佳解答

如果你後端有用php的話,你可以寫一枝
getPingTung.php , 內容是

<?php
header('Access-Control-Allow-Origin: *'); 
header("Content-Type: text/html; charset=utf-8");

$text = file_get_contents('http://i-pingtung.com/OpenData/Attractions?start=100&limit=2000');
$tt = mb_convert_encoding($text, 'UTF-8',
          mb_detect_encoding($text, 'UTF-8, big5', true));
echo $tt;

?>

而前端網頁,變成

<script>

$.ajax({
  dataType: "json",
  url: "getPingTung.php",
  success: function(data){
                console.log(data);
            }
});
</script>

會自動幫你轉成json 物件。

Address:"內田村廣濟路164號"
AddressCounty:"屏東縣"
AddressTownship:"內埔鄉"
Alias:""
ClickCount:5241
Coordinate:"22.6152,120.566"
CoordinateLevel:14
Driving:"屏東九如交流道→台3線→台1線→信義路→台1線 →自強路→廣濟路→昌黎祠"
Elong:120.566
Email:""
Enable:true
Fax:""

這個資料結構有點複雜,一對多的關係。一個景點有多張照片。肉容挺豐富的。

https://ithelp.ithome.com.tw/upload/images/20171006/200452300Zjuf6XKii.jpg

2
海綿寶寶
iT邦超人 1 級 ‧ 2017-09-06 09:20:51

我猜可能是因為 content-type 的原因
Vue 預期的是 application/json
而 i-pingtung.com 傳的是 text/html

可以試試看拿以下這段 code 去改
讓 Vue 強迫去讀 text/html 的 content-type

Vue.http.interceptors.push((request, next ) => {
    next((response) => {
        if( 'Content-Type' in response.headers 
            && response.headers['Content-Type'] == 'application/json' ){
            if( typeof response.data != 'object' ){
                response.data = JSON.parse( response.data );
            }
        }

        if( 'content-type' in response.headers
            && response.headers['content-type'] == 'application/json' ){
            if( typeof response.data != 'object' ){
                response.data = JSON.parse( response.data );
            }
        }
    });
});

以上程式碼的來源如下
如何讓 Vue 支援小寫的 content-type

0
vt167098
iT邦新手 4 級 ‧ 2017-10-12 08:23:27

跨網域存取也可以用爬蟲的方式將網頁抓回來後,再處理出自己要的資料.
可以google關鍵字'cheerio'

我要發表回答

立即登入回答