政府資料開放平臺 (DATA.GOV.TW) 上提供的資料有 xml, json, csv, 甚至是 pdf, zip 等格式,我們將針對 JSON 這個目前相當普遍使用的資料交換格式介紹從客戶端 (Client) 取得政府資料開放平臺上的 JSON 格式資料的方式。本篇僅介紹取得資料的技術,若想對政府資料開放平臺和 JSON 有更多的了解,可以到下列網站:
本篇介紹的方式包含由客戶端直接取得政府資料開放平臺上 JSON 資料的三個方式:
Javascript XMLHttpRequest, jQuery getJSON(), jQuery ajax()
如果客戶端無法直接取得資料,使用伺服器端 (server) PHP 或以 Python 取得 JSON 資料的方式。
我們的目標是開發 Web 或 Web App,將取得資料的工作交由客戶端可以減輕 server 的負擔,所以先來了解怎麼從客戶端直接取得 JSON 資料。
方法1 - Javascript XMLHttpRequest
XMLHttpRequest 物件會開啟 URL,並發起 HTTP 請求,XMLHttpRequest 可以很簡單的設定為同步 (synchronous) 或非同步 (asynchronous) 請求。以下就是 Javascript 以 XMLHttpRequest 物件取得 JSON 資料的方式,資料取得成功會呼叫 myFunction(xmlhttp.responseText),取得的 JSON 資料就在 xmlhttp.responseText 中。以下是 XMLHttpRequest 方法的程式碼和解說:
var xmlhttp = new XMLHttpRequest(); // 建立XMLHttpRequest物件 var url = ""; // 欲取得的JSON資料網址url xmlhttp.onreadystatechange=function() { if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { // 資料取得成功呼叫自訂函數 myFunction() myFunction(xmlhttp.responseText); // xmlhttp.responseText中就是取得的資料 } } xmlhttp.open("GET", url, true); // 使用GET方法,true --> 非同步(asynchronous) xmlhttp.send(); // 送出請求您可以在自訂函數 myFunction(xmlhttp.responseText) 中對取得的 JSON 資料作進一步的處理。我們以政府資料開放平臺提供的文化部音樂表演資訊,試作一個簡單的完整範例,這個例子加上了Bootstrap美化表格,若不需要就將Bootstrap的引用刪除:
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- Bootstrap CSS & JS 若不使用Bootstrap可將以下4行引用刪除--> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script> <script> var xmlhttp = new XMLHttpRequest(); var url = "https://cloud.culture.tw/frontsite/trans/SearchShowAction.do?method=doFindTypeJ&category=1"; xmlhttp.onreadystatechange=function() { if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { myFunction(xmlhttp.responseText); } } xmlhttp.open("GET", url, true); xmlhttp.send(); function myFunction(response) { var arr = JSON.parse(response); var i; var out = '<table class="table table-striped table-hover">' + '<thead><tr><th scope="col">#</th>' + '<th scope="col">活動名稱</th>' + '<th scope="col">主辦單位</th>' + '<th scope="col">活動時間</th>' + '<th scope="col">活動售票</th></tr></thead><tbody>'; for(i = 0; i < arr.length; i++) { out += '<tr><th scope="row">' + i + '</th><td>' + arr[i].title + "</td><td>" + arr[i].masterUnit + "</td><td>" + arr[i].startDate + "</td><td>" + arr[i].sourceWebName + "</td></tr>"; } out += "</tbody></table>"; document.getElementById("showData").innerHTML = out; } </script> </head> <body> <h2>Get JSON Open Data Example</h2> <h4>文化部-音樂表演資訊</h4> <div id="showData"></div> </body> </html>
方法2 - jQuery getJSON()
getJSON() 是 jQuery 提供可向伺服器發出取回 JSON 資料的 AJAX HTTP GET 請求,它是一個簡單版的 ajax 方法。以下是 getJSON() 方法的程式碼和解說:
jQuery(document).ready(function(){ // 將$.getJSON()放在document.ready事件中 var jqxhr = $.getJSON(url, function(arr) { // url是JSON資料的網址,取得的資料存在arr變數中 console.log("success"); // 請求成功會執行此區塊,可在此處理JSON資料 }).done(function(arr) { console.log("second success"); // 另一個請求成功會執行的區塊,也可在此處理JSON資料 }).fail(function() { console.log("error"); // 請求失敗會執行這個區塊 }).always(function() { console.log("complete"); // 無論請求成功或失敗都會執行的區塊 }); });同樣以政府資料開放平臺提供的文化部音樂表演資訊,試作一個簡單的getJSON()完整範例,注意因為使用getJSON()需引用jQuery JS:
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- Bootstrap CSS & JS 若不使用Bootstrap可將以下4行引用刪除 --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script> <!-- 使用getJSON()需引用jQuery --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <script> jQuery(document).ready(function(){ var url = "https://cloud.culture.tw/frontsite/trans/SearchShowAction.do?method=doFindTypeJ&category=1"; var jqxhr = $.getJSON(url, function(arr) { console.log("success"); var i; var out = '<table class="table table-striped table-hover">' + '<thead><tr><th scope="col">#</th>' + '<th scope="col">活動名稱</th>' + '<th scope="col">主辦單位</th>' + '<th scope="col">活動時間</th>' + '<th scope="col">活動售票</th></tr></thead><tbody>'; for(i = 0; i < arr.length; i++) { out += '<tr><th scope="row">' + i + '</th><td>' + arr[i].title + "</td><td>" + arr[i].masterUnit + "</td><td>" + arr[i].startDate + "</td><td>" + arr[i].sourceWebName + "</td></tr>"; } out += "</tbody></table>"; document.getElementById("showData").innerHTML = out; }).done(function() { console.log("second success"); }).fail(function() { console.log( "error" ); }).always(function() { console.log( "complete" ); }); }); </script> </head> <body> <h2>Get JSON Open Data Example</h2> <h4>文化部-音樂表演資訊</h4> <div id="showData"></div> </body> </html>
方法3 - jQuery ajax()
使用非同步 JavaScript 及 XML(Asynchronous JavaScript and XML,AJAX),以下是 ajax() 方法的程式碼和解說:
jQuery(document).ready(function(){ // 將$.ajax()放在document.ready事件中 $.ajax({ type: "GET", // 使用GET方法 url: "", // 取得JSON資料的網址 dataType: "json", // 資料類型 json async: true, // true(非同步請求 defaule), false(同步請求) success: function(arr) { // 取得的資料存在變數arr中 // 請求成功執行的區塊,可在此處理JSON資料 } }); });同樣以政府資料開放平臺提供的文化部音樂表演資訊,試作一個簡單的ajax()完整範例,注意因為使用ajax()需引用jQuery JS:
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- Bootstrap CSS & JS 若不使用Bootstrap可將以下4行引用刪除 --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script> <!-- 使用ajax()需引用jQuery --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <script> jQuery(document).ready(function(){ $.ajax({ type: "GET", url: "https://cloud.culture.tw/frontsite/trans/SearchShowAction.do?method=doFindTypeJ&category=1", dataType: "json", async: true, success: function(arr) { console.log("success!"); var i; var out = '<table class="table table-striped table-hover">' + '<thead><tr><th scope="col">#</th>' + '<th scope="col">活動名稱</th>' + '<th scope="col">主辦單位</th>' + '<th scope="col">活動時間</th>' + '<th scope="col">活動售票</th></tr></thead><tbody>'; for(i = 0; i < arr.length; i++) { out += '<tr><th scope="row">' + i + '</th><td>' + arr[i].title + "</td><td>" + arr[i].masterUnit + "</td><td>" + arr[i].startDate + "</td><td>" + arr[i].sourceWebName + "</td></tr>"; } out += "</tbody></table>"; document.getElementById("showData").innerHTML = out; } }); }); </script> </head> <body> <h2>Get JSON Open Data Example</h2> <h4>文化部-音樂表演資訊</h4> <div id="showData"></div> </body> </html>
方法4 - 使用 PHP
如果無法從前端直接抓資料,因同源政策(Same-origin policy) 或 cross-domain error,則可由伺服器端以 PHP 抓取。PHP 提供了 file_get_contents 和 curl 方法來取得 JSON 資料。 PHP 應該就一定可以抓取了。以下是這兩個方法的參考資料及使用方式:
PHP - file_get_contents() 使用方式:
<?php $url = ""; // Your json data url $data = file_get_contents($url); // PHP get data from url $json = json_decode($data, true); // Decode json data // 處理取得的 json 資料 ?>PHP - curl 使用方式:
<?php $url = ""; // Your json data url $ch = curl_init(); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_URL, $url); $data = curl_exec($ch); curl_close($ch); $json = json_decode($data); // Decode json data // 處理取得的 json 資料 ?>
方法5 - 使用 Python
也可以從伺服器端以 Python 抓取,然後存成 .json 檔放在伺服器上, Python 抓取 JSON 資料的方式如下:
import requests data = requests.get(url="") // Your json data url print(data.json()) // 檢視取回的json資料可將抓取回來的 JSON Data 存成 .json 檔,程式碼如下:
import requests import json data = requests.get(url="http://cloud.culture.tw/frontsite/trans/SearchShowAction.do?method=doFindTypeJ&category=3") with open("a.json","w",encoding="utf-8") as myFile: // 開啟檔案以寫入JSON資料 json.dump(data.json(), myFile,ensure_ascii=False) myFile.close()以上就是本篇介紹取得政府資料開放平臺 JSON 格式資料的方式。
參考資料 (References):
😺 jQuery 官方文件 - jQuery.getJSON()