友的單位有一個小型的圖書室,圖書室中擺放了很多的書,每本書都被編號放在對應的區域,為了讓大家更快、更容易找到這些書,他聯系我,讓我幫他弄一個圖書查詢系統,通過用戶輸入能模糊匹配到對應的結果,并且提供書籍對應的地點。
Excel 樣式主要包括書名和編號,同時下面包括分類的 tab:
核心代碼實現:
復制代碼已復制
import jiebaimport openpyxlfrom gensim import corpora, models, similaritiesfrom collections import defaultdictimport urllib.request with open("/tmp/book.xlsx", "wb") as f: f.write( urllib.request.urlopen("https://********").read() ) top_str = "abcdefghijklmn"book_dict = {}book_list = []wb = openpyxl.load_workbook('/tmp/book.xlsx')sheets = wb.sheetnamesfor eve_sheet in sheets: print(eve_sheet) sheet = wb.get_sheet_by_name(eve_sheet) this_book_name_index = None this_book_number_index = None for eve_header in top_str: if sheet[eve_header][0].value == " 書名 ": this_book_name_index = eve_header if sheet[eve_header][0].value == " 編號 ": this_book_number_index = eve_header print(this_book_name_index, this_book_number_index) if this_book_name_index and this_book_number_index: this_book_list_len = len(sheet[this_book_name_index]) for i in range(1, this_book_list_len): add_key = "%s_%s_%s" % ( sheet[this_book_name_index][i].value, eve_sheet, sheet[this_book_number_index][i].value) add_value = { "category": eve_sheet, "name": sheet[this_book_name_index][i].value, "number": sheet[this_book_number_index][i].value } book_dict[add_key] = add_value book_list.append(add_key) def getBookList(book, book_list): documents = [] for eve_sentence in book_list: tempData = " ".join(jieba.cut(eve_sentence)) documents.append(tempData) texts = [[word for word in document.split()] for document in documents] frequency = defaultdict(int) for text in texts: for word in text: frequency[word] += 1 dictionary = corpora.Dictionary(texts) new_xs = dictionary.doc2bow(jieba.cut(book)) corpus = [dictionary.doc2bow(text) for text in texts] tfidf = models.TfidfModel(corpus) featurenum = len(dictionary.token2id.keys()) sim = similarities.SparseMatrixSimilarity( tfidf[corpus], num_features=featurenum )[tfidf[new_xs]] book_result_list = [(sim[i], book_list[i]) for i in range(0, len(book_list))] book_result_list.sort(key=lambda x: x[0], reverse=True) result = [] for eve in book_result_list: if eve[0] >= 0.25: result.append(eve) return result def main_handler(event, context): try: print(event) name = event["body"] print(name) base_html = '''<div class='mui-card'><div class='mui-card-header'>{{book_name}}</div><div class='mui-card-content'><div class='mui-card-content-inner'> 分類:{{book_category}}<br> 編號:{{book_number}}</div></div></div>''' result_str = "" for eve_book in getBookList(name, book_list): book_infor = book_dict[eve_book[1]] result_str = result_str + base_html.replace("{{book_name}}", book_infor['name']) \ .replace("{{book_category}}", book_infor['category']) \ .replace("{{book_number}}", book_infor['number'] if book_infor['number'] else "") if result_str: return result_str except Exception as e: print(e) return '''<div class='mui-card' style='margin-top: 25px'><div class='mui-card-content'><div class='mui-card-content-inner'> 未找到圖書信息,請您重新搜索。</div></div></div>'''
同時配置 APIGW:
復制代碼已復制
<!DOCTYPE html><html><head> <meta charset="utf-8"> <title> 圖書檢索系統 </title> <meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1,user-scalable=no"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <link rel="stylesheet" href="https://others-1256773370.cos.ap-chengdu.myqcloud.com/booksearch/css/mui.min.css"> <style> html, body { background-color: #efeff4; } </style> <script> function getResult() { var UTFTranslate = { Change: function (pValue) { return pValue.replace(/[^\u0000-\u00FF]/g, function (><!DOCTYPE html><html><head> <meta charset="utf-8"> <title> 圖書檢索系統 </title> <meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1,user-scalable=no"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <link rel="stylesheet" href="https://others-1256773370.cos.ap-chengdu.myqcloud.com/booksearch/css/mui.min.css"> <style> html, body { background-color: #efeff4; } </style> <script> function getResult() { var UTFTranslate = { Change: function (pValue) { return pValue.replace(/[^\u0000-\u00FF]/g, function ($0) { return escape($0).replace(/(%u)(\w{4})/gi, "$2;") }); }, ReChange: function (pValue) { return unescape(pValue.replace(//g, '%u').replace(/\\u/g, '%u').replace(/;/g, '')); } }; var xmlhttp; if (window.XMLHttpRequest) { // IE7+, Firefox, Chrome, Opera, Safari 瀏覽器執行代碼 xmlhttp = new XMLHttpRequest(); } else { // IE6, IE5 瀏覽器執行代碼 xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.onreadystatechange = function () { if (xmlhttp.readyState == 4 && xmlhttp.status == 200 && xmlhttp.responseText) { document.getElementById("result").innerHTML = UTFTranslate.ReChange(xmlhttp.responseText).slice(1, -1).replace("\"",'"'); } } xmlhttp.open("POST", "https://********", true); xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); xmlhttp.send(document.getElementById("book").value); } </script></head><body><div class="mui-content" style="margin-top: 50px"> <h3 style="text-align: center"> 圖書檢索系統 </h3> <div class="mui-content-padded" style="margin: 10px; margin-top: 20px"> <div class="mui-input-row mui-search"> <input type="search" class="mui-input-clear" placeholder=" 請輸入圖書名 " id="book"> </div> <div class="mui-button-row"> <button type="button" class="mui-btn mui-btn-numbox-plus" style="width: 100%" onclick="getResult()"> 檢索 </button> </div> </div> <div id="result"> <div class="mui-card" style="margin-top: 25px"> <div class="mui-card-content"> <div class="mui-card-content-inner"> 可以在搜索框內輸入書籍的全稱,或者書籍的簡稱,系統支持智能檢索功能。 </div> </div> </div> </div></div><script src="https://others-1256773370.cos.ap-chengdu.myqcloud.com/booksearch/js/mui.min.js"></script></body></html><) { return escape(><!DOCTYPE html><html><head> <meta charset="utf-8"> <title> 圖書檢索系統 </title> <meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1,user-scalable=no"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <link rel="stylesheet" href="https://others-1256773370.cos.ap-chengdu.myqcloud.com/booksearch/css/mui.min.css"> <style> html, body { background-color: #efeff4; } </style> <script> function getResult() { var UTFTranslate = { Change: function (pValue) { return pValue.replace(/[^\u0000-\u00FF]/g, function ($0) { return escape($0).replace(/(%u)(\w{4})/gi, "$2;") }); }, ReChange: function (pValue) { return unescape(pValue.replace(//g, '%u').replace(/\\u/g, '%u').replace(/;/g, '')); } }; var xmlhttp; if (window.XMLHttpRequest) { // IE7+, Firefox, Chrome, Opera, Safari 瀏覽器執行代碼 xmlhttp = new XMLHttpRequest(); } else { // IE6, IE5 瀏覽器執行代碼 xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.onreadystatechange = function () { if (xmlhttp.readyState == 4 && xmlhttp.status == 200 && xmlhttp.responseText) { document.getElementById("result").innerHTML = UTFTranslate.ReChange(xmlhttp.responseText).slice(1, -1).replace("\"",'"'); } } xmlhttp.open("POST", "https://********", true); xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); xmlhttp.send(document.getElementById("book").value); } </script></head><body><div class="mui-content" style="margin-top: 50px"> <h3 style="text-align: center"> 圖書檢索系統 </h3> <div class="mui-content-padded" style="margin: 10px; margin-top: 20px"> <div class="mui-input-row mui-search"> <input type="search" class="mui-input-clear" placeholder=" 請輸入圖書名 " id="book"> </div> <div class="mui-button-row"> <button type="button" class="mui-btn mui-btn-numbox-plus" style="width: 100%" onclick="getResult()"> 檢索 </button> </div> </div> <div id="result"> <div class="mui-card" style="margin-top: 25px"> <div class="mui-card-content"> <div class="mui-card-content-inner"> 可以在搜索框內輸入書籍的全稱,或者書籍的簡稱,系統支持智能檢索功能。 </div> </div> </div> </div></div><script src="https://others-1256773370.cos.ap-chengdu.myqcloud.com/booksearch/js/mui.min.js"></script></body></html><).replace(/(%u)(\w{4})/gi, "") }); }, ReChange: function (pValue) { return unescape(pValue.replace(//g, '%u').replace(/\u/g, '%u').replace(/;/g, '')); } }; var xmlhttp; if (window.XMLHttpRequest) { // IE7+, Firefox, Chrome, Opera, Safari 瀏覽器執行代碼 xmlhttp = new XMLHttpRequest(); } else { // IE6, IE5 瀏覽器執行代碼 xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.onreadystatechange = function () { if (xmlhttp.readyState == 4 && xmlhttp.status == 200 && xmlhttp.responseText) { document.getElementById("result").innerHTML = UTFTranslate.ReChange(xmlhttp.responseText).slice(1, -1).replace("\"",'"'); } } xmlhttp.open("POST", "https://********", true); xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); xmlhttp.send(document.getElementById("book").value); } </script></head><body><div class="mui-content" style="margin-top: 50px"> <h3 style="text-align: center"> 圖書檢索系統 </h3> <div class="mui-content-padded" style="margin: 10px; margin-top: 20px"> <div class="mui-input-row mui-search"> <input type="search" class="mui-input-clear" placeholder=" 請輸入圖書名 " id="book"> </div> <div class="mui-button-row"> <button type="button" class="mui-btn mui-btn-numbox-plus" style="width: 100%" onclick="getResult()"> 檢索 </button> </div> </div> <div id="result"> <div class="mui-card" style="margin-top: 25px"> <div class="mui-card-content"> <div class="mui-card-content-inner"> 可以在搜索框內輸入書籍的全稱,或者書籍的簡稱,系統支持智能檢索功能。 </div> </div> </div> </div></div><script src="https://others-1256773370.cos.ap-chengdu.myqcloud.com/booksearch/js/mui.min.js"></script></body></html>
為了便于朋友使用,我將這個頁面用 Webview 封裝成一個 APP,整體效果如下:
這是一個低頻使用的 APP,如果是構建在傳統服務器上,不是一個明智的選擇,而云函數的按量付費,對象存儲與 APIGW 的融合,完美解決了資源浪費的問題,同時借用云函數的 APIGW 觸發器,可以很簡單輕松的替代傳統的 Web 框架和部分服務器軟件的安裝和使用、維護等。這個例子非常小,但卻是一個有趣的小工具,除了圖書查詢之外,我們還可以繼續拓展構建其它系統,例如成績查詢等。
關注我并轉發此篇文章,私信我“領取資料”,即可免費獲得InfoQ價值4999元迷你書!
MLHttpRequest(oXMLHttpRequest) 對象屬性
onreadystatechange 狀態改變的事件觸發器,只寫;
XMLHttpRequest.onreadystatechange = funcMyHandler;
readyState 對象狀態(integer),只讀;
XMLHttpRequest.readyState;
0 = 未初始化 1 = 初始化 2 = 已發送 3 = 已接收部分數據 4 = 完成
0 (未初始化) 對象已建立, 但是尚未初始化---創建ajax對象(new XMLHttpRequest)
1 (初始化) 對象已初始化, 尚未調用send方法---初始化ajax對象(xmlHttp.open())
2 (發送數據) send方法已調用, 但是當前的狀態及http頭未知----發送請求(xmlHttp.send())
3 (數據傳送中) 已接收部分數據, 因為響應及http頭不全, 這時通過responseBody和responseText獲取部分數據會出現錯誤,
4 (完成) 數據接收完畢, 此時可以通過通過responseBody和responseText獲取完整的回應數據
responseText 服務器進程返回數據的文本版本,只讀;(text/html)
strValue = XMLHttpRequest.responseText;(text/html)
strXML = XMLHttpRequest.responseXML;(text/xml)
status 服務器返回的狀態碼, 如:404 = "文件末找到" 、200 ="成功"
XMLHttpRequest.status;
常用的值有:
200 表示請求成功
202 表示被接收
400 表示錯誤的請求
404 表示資源未找到
500 表示內部服務器錯誤, 如php代碼錯誤等
statusText 服務器返回的狀態文本信息,如:ok、not found
strValue = XMLHttpRequest.statusText;
Ajax引擎對象中的方法
abort() 停止當前請求
XMLHttpRequest.abort();
getAllResponseHeaders() 作為字符串返回完整的headers
strValue = XMLHttpRequest.getAllResponseHeaders();
getResponseHeader() 作為字符串返回單個的header標簽
strValue = XMLHttpRequest.getResponseHeader();
如:XMLHttpRequest.getResponseHeader("Server")
open("method","URL"[,asyncFlag[,"userName"[, "password"]]]) 設置未決的請求的目標 URL,方法,和其他參數
method:http方法, 例如:POST、GET、PUT及PROPFIND。大小寫不敏感。
URL:請求的URL地址,可以為絕對地址也可以為相對地址。
asyncFlag[可選]:布爾型,指定此請求是否為異步方式,默認為true。如果為真, 當狀態改變時會調用onreadystatechange屬性指定的回調函數。
異步:同一個時間點允許執行多個進程。(true)
同步:同一個時間點只允許執行一個進程。(false)
userName[可選]:如果服務器需要驗證,此處指定用戶名,如果未指定,當服務器需要驗證時,會彈出驗證窗口。
password[可選]:驗證信息中的密碼部分,如果用戶名為空,則此值將被忽略。
send(content) 發送請求
只有當ajax對象的send方法被調用時,才會發送請求
注意:
使用get將數據傳給服務器,則服務器就使用$_GET
就直接通過url將數據傳給服務器,發送請求使用send(null)語句
使用POST時一定要使用 xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
發送請求使用send(url)語句;
通常在數據不多的時候才有GET方式,而數據量稍大的時候采用POST方式
setRequestHeader("header", "value") 設置header并和請求一起發送
xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
完整實例:
<!DOCTYPE html>
<html>
<head>
<title>XMLHttpRequest</title>
<script language="javascript">
var xmlHttp;
function createXMLHttpRequest(){
if(window.ActiveXObject)
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
else if(window.XMLHttpRequest)
xmlHttp = new XMLHttpRequest();
}
function startRequest(){
createXMLHttpRequest();
var sUrl = "sync.php?" + new Date().getTime(); //地址不斷的變化,解決IE緩存問題
xmlHttp.onreadystatechange = function(){
if(xmlHttp.readyState == 4 && xmlHttp.status == 200)
alert("服務器返回: " + xmlHttp.responseText);
}
xmlHttp.open("GET",sUrl,true);
xmlHttp.send(null);
}
</script>
</head>
<body>
<input type="button" value="測試異步通訊" onClick="startRequest()">
</body>
</html>
服務器端代碼(文件名:sync.php)
<?php
header('Content-type: text/html;charset=utf-8');
echo "異步測試成功,很高興";
?>
服務器端在返回數據時可不可以使用return代替echo?
答:不可以
原因如下:雖然return與echo都有返回的含義, 但是兩者有很大的區別。return代表返回數據到服務器端, 而echo語句代表返回數據到客戶端。
又由于Ajax屬于客戶端語言, 其接收的數據必須能返回到客戶端, 否則是接收不到任何數據的。
ajax
avaScript 最早誕生于1995年,當時主要用來處理輸入驗證操作,隨著時間的發展它成為了市面上瀏覽器必備的一項功能。如今JavaScript不僅僅局限于簡單的數據校驗,它已經具備與瀏覽器窗口及其內容幾乎所有方面的交互能力,已經是一個功能全面的編程語言,能夠處理復雜的交互和計算。
1995年Netscape 公司的布蘭登.艾奇(Brendan Eich)著手開發一種名為 LiveScript的腳步語言。主要用于 Netscape Navigator 瀏覽器上,為了趕在瀏覽器發布前完成Livescript 的開發,Netscape 便和 Sun 公司合作,因此Netscape 為了搭上 Java的順風車,把Livescrip改名JavaScript。
由于JavaScript 1.0版的巨大成功,成為了市場的領袖型公司,在當時的背景下,微軟在其ie 3中加入了名為JScript的腳本語言,隨著微軟的加入,市場上出現多個不同版本的JavaScript,導致每個版本差異巨大,沒有統一的標準,引起了許多問題。
于是在1997年,以JavaScript 1.1為基礎版本提交給歐洲計算機制造商協會(ECMA)。隨后,該協會推出了ECMAScript標準,各瀏覽器廠商都將此標準作為實現各自JavaScript的實現基礎,也在不同程度上取得成功。
雖然通常JavaScript 和 ECMAScript被認為是相同的含義,但是JavaScript卻比ECMA規定的內容要多得多。一個完整的JavaScript 由以下組成:
ECMAScript 其實與web瀏覽器沒有依賴關系,它不依賴任何環境,web瀏覽器只是其實現的一種宿主環境。此外還有Node 和 Flash 也都是宿主環境,都實現了各自的ECMAScript 腳本。
ECMAScript 主要有以下核心內容:
2015年6月17日,ECMAScript 6發布正式版本,即ECMAScript 2015,簡稱ES6,ES6增添了許多必要的特性,例如:模塊和類,以及一些實用特性,例如Maps、Sets、Promises、生成器(Generators)等。盡管ES6做了大量的更新,但是它依舊完全向后兼容以前的版本。
截止目前,ES6是各大瀏覽器支持較好的且穩定的一個版本,以后關于JavaScript的知識都會在ES6的語法基礎上介紹。
文檔對象模型(Document Object Model),是針對XML及其基礎上擴展的HTML的應用程序編程接口(API)。DOM把整個網頁映射成為一個樹狀的多層節點結構。頁面中每個組成部分都是某種類型的節點,這些節點有包含不同的數據。如下面這個html頁面:
<html>
<head>
<title>標題</title>
</head>
<body>
<p>段落文字</p>
</body>
</html>
通過DOM構建的節點樹結構,我們可以很方便的控制頁面的內容,比如刪除、添加、修改任何節點的內容。
DOM主要內容
DOM 作為一種API,它也是有規范的,1998年DOM成為W3C的推薦標準,DOM從1.0到如今的3.0,其實現了更加豐富的接口,主要有如下這些模塊:
處理DOM核心和DOM HTML接口外,另外其它語言也發布了針對自己的DOM標準。比如下面幾種:
還有一些語言,比如 Mozilla 的XUL(XML 用戶界面語言),但是只有上面幾種是W3C推薦的標準。
如今,大部分瀏覽器已經全部支持DOM 1.0 、2.0版,3.0版也大部分都支持,所以我們可以放心的使用,尤其是最近IE瀏覽器的徹底退出舞臺,瀏覽器兼容問題少了許多。
早期Netscape 瀏覽器和IE瀏覽器,都支持訪問和操作瀏覽器窗口對象模型。開發者可以控制頁面以外的部分,不同于其它,BOM作為JavaScript的實現卻沒有一個相關的標準。這個問題直到HTML5出現才得到解決,HTML5致力于把BOM納入正式的規范中。
BOM從根本上講,只處理瀏覽器窗口和框架,但人們都習慣把針對瀏覽器的JavaScript擴展歸于BOM的范疇,下面是一些擴展:
由于BOM一直以來沒有統一的規范,各個瀏覽器都有自己的實現,所以差距比較大,但是隨著HTML5的發展,BOM朝著兼容性更高的方向發展。
JavaScript 是一種專門為網頁設計的腳本語言,其主要由以下三個部分組成:
在當前主流瀏覽器中,對于ES6的大部分功能都得到了支持,隨著技術的發展,JavaScript越來越完善,功能也更加強大。
參考資料:
《JavaScript 高級程序設計》第三版
MDN JavaScript 教程 —— https://developer.mozilla.org/zh-CN/docs/Web/JavaScript
*請認真填寫需求信息,我們會在24小時內與您取得聯系。