使用Python的http.server實現一個簡易的Web Api對外提供HanLP拼音轉換服務
由於採集省市區鎮資料需要對地名進行拼音轉換,由於第三方高準確度介面對IP進行了限制,處理大量資料變得異常緩慢。
使用了一個折中的辦法,省市區 3級
(3千+)用高準確度介面(幾乎沒有拼錯的地名),鎮級
(4萬+)用本地HanLP
提供的介面(大部分多音字還算是能拼正確)。
Github原始碼:https://github.com/xiangyuecn/AreaCity-JsSpider-StatsGov/tree/master/.pinyin-python-server
另外我提供了一個臨時測試伺服器,國內的但域名備案掉了走的海外線路,僅供測試,隨時可能關閉。測試:http://pinyin-test.haozgz.com/pinyin?txt=重慶著陸OK,重力看著沒有異常 。
HanLP
是一個優秀的開源自然語言處理工具,提供了頗為準確的拼音轉換功能。開始本想使用更為順手的nodejs
來處理,但測試了Github上排第一的hotoo/pinyin
庫,就是開了分詞,對多音字支援也不太理想。最後決定使用HanLP
Python版
來進行轉換,但是這個庫對地名的支援還是有限,都
字地名很多轉換成dou
囧,不過在同類型裡面算是最好的。
新手第一次正經寫Python程式碼,剛開始電腦上以前裝的Python 2.7.x
,就按Python2寫了一個服務,發現字串編碼需要轉來轉去,夠折騰的,但好歹功能沒問題。後面因為這個編碼問題,越想越覺得不舒服,一個優秀的語言哪有這麼折騰的,就改成了3.6.x
(Miniconda裡面3.7.x
環境SSL有問題,pip用不了,不願折騰了)。最終結果就是僅支援Python3
,沒有了奇異的程式碼。
http.server的簡單上手
建立服務
網上有很多例子,也都非常簡單,這個玩意也很容易上手。幾行程式碼就能建立一個HTTP服務功能。
from http.server import HTTPServer, BaseHTTPRequestHandler class HttpHandler(BaseHTTPRequestHandler): def do_GET(self): #服務功能實現 def do_POST(self): #服務功能實現 httpd = HTTPServer(('127.0.0.1', 9527), HttpHandler) httpd.serve_forever()
和nodejs
的http
模組寫出來的服務一樣簡潔。只監聽127.0.0.1
省的配置防火牆,只讓本機訪問。
接收請求引數
一個Web Api不僅僅有path
,還要有query string
x-www-form-urlencoded
請求引數支援。urllib.parse.parse_qs
能輕鬆解析出請求資料。
class HttpHandler(BaseHTTPRequestHandler): def do_GET(self): path,args=urllib.parse.splitquery(self.path) self._response(path, args) def do_POST(self): args = self.rfile.read(int(self.headers['content-length'])).decode("utf-8") self._response(self.path, args) def _response(self, path, args): if args: args=urllib.parse.parse_qs(args).items() args=dict([(k,v[0]) for k,v in args]) else: args={} # 輕鬆就解析出了請求引數物件
執行實際業務邏輯
有了path
和args
,就直接可以上業務邏輯了。具體這個請求是要處理什麼功能,根據path
來判斷一下即可,功能需要的引數從args
裡面取。
整個拼音服務完整程式碼
from pyhanlp import * import traceback import json import urllib from http.server import HTTPServer, BaseHTTPRequestHandler class HttpHandler(BaseHTTPRequestHandler): def _response(self, path, args): code=200 rtv={'c':0,'m':'','v':''} try: if args: args=urllib.parse.parse_qs(args).items() args=dict([(k,v[0]) for k,v in args]) else: args={} # **************************************** # ***************頁面開始***************** # **************************************** # ==> if path=="/": rtv["v"]="伺服器已準備好" # ==> elif path=="/pinyin": txt=args.get("txt","") pinyin_list = HanLP.convertToPinyinList(txt) list=[] Pinyin=JClass("com.hankcs.hanlp.dictionary.py.Pinyin") for i in range(pinyin_list.size()): pinyin=pinyin_list[i] if pinyin==Pinyin.none5: list.append('F'+txt[i]) else: list.append(pinyin.getPinyinWithoutTone()) rtv["v"]=list # **************************************** # ****************頁面結束**************** # **************************************** else: code=404 rtv["c"]=404 rtv["m"]="路徑"+path+"不存在" except Exception as e: rtv["c"]=1 rtv["m"]='伺服器錯誤:'+str(e)+"\n"+traceback.format_exc() try: rtv=json.dumps(rtv,ensure_ascii=False) except Exception as e: rtv={'c':2,'m':'伺服器返回資料錯誤:'+str(e)+"\n"+traceback.format_exc(),'v':''} rtv=json.dumps(rtv,ensure_ascii=False) self.send_response(code) self.send_header('Content-type', 'text/json; charset=utf-8') self.send_header('Access-Control-Allow-Origin', '*') self.end_headers() self.wfile.write(rtv.encode()) def do_GET(self): path,args=urllib.parse.splitquery(self.path) self._response(path, args) def do_POST(self): args = self.rfile.read(int(self.headers['content-length'])).decode("utf-8") self._response(self.path, args) httpd = HTTPServer(('127.0.0.1', 9527), HttpHandler) httpd.serve_forever()
HanLP的安裝
由於HanLP
是一個java庫
,因此使用了pyhanlp
這個Python包,底層還是用jpype1
來呼叫HanLP
的java
介面。Windows上還是根據wiki
來完成的安裝,這庫給予了蠻實用的安裝方法。
本方法只在windows 7 環境下執行過,其他環境自測。
:: 安裝一個有效的版本 > conda create -n python364 python=3.6.4 :: 切換版本 > activate python364 :: 安裝jpype1 > conda install -c conda-forge jpype1 :: 安裝pyhanlp > pip install pyhanlp :: 執行一遍,會提示要下載哪些東西 > hanlp :: 環境都搞定後就可以執行服務了 > python server.py
【1】安裝Miniconda
conda版本隨意,https://conda.io/miniconda.html
【2】安裝pyhanlp
參考:https://github.com/hankcs/pyhanlp/wiki/Windows
這個庫是java
庫,需要有java
環境,如果沒有裝過,需要先安裝java
:下載JDK
測試發現python3.7.1
windows
下ssl
有問題無法安裝,conda
切換成python 3.6.4
測試安裝正常
安裝好後執行一下hanlp
命令,會提示下載,看第3步
如果出現XXX.dll
什麼的問題,可能是C++執行庫缺失,安裝微軟常用執行庫合集
應該能夠解決,我在Windows Server 2012
上使用時出現此問題,裝上就OJBK了。
【3】下載字典和jar
參考半自動配置:https://github.com/hankcs/pyhanlp/wiki/%E6%89%8B%E5%8A%A8%E9%85%8D%E7%BD%AE 。
字典和jar存放目錄一般在Miniconda3[\envs\py36]\Lib\site-packages\pyhanlp\static
。
jar
直接下載最新releases
。
字典最好直接clone
倉庫/data目錄
最新版本(用svn
下載速度快很多,無需model
資料),一樣的在儲存目錄內放一個data
資料夾,releases
對bug處理稍微滯後一點。
另外需要修改hanlp.properties
,給root
賦值為當前目錄完整路徑。
svn:https://github.com/hankcs/HanLP/trunk/data
【4】執行
python server.py
【5】瀏覽器訪問
http://127.0.0.1:9527/pinyin?txt=要拼的文字
比如:拼音。m
返回結果{c:0,m:"",v:["pin","yin","F。","Fm"]}
,c=0時代表正常,其他代表出錯,m為錯誤原因,拼音如果是字母符號會用F打頭。
最後
Github原始碼:https://github.com/xiangyuecn/AreaCity-JsSpider-StatsGov/tree/master/.pinyin-python-server 。
如果這個庫有幫助到您,請 Star 一下。