Python 小白的入門實(shí)戰(zhàn)——利用百度API自動(dòng)獲取數(shù)據(jù)

前言

我是一名Python小白喳篇,兩個(gè)禮拜之前還對(duì)Python一無所知迅矛,上次我利用舉辦社團(tuán)活動(dòng)的契機(jī)型宝,請(qǐng)學(xué)校老師做了一次Python入門講座臭挽。聽聞Python功能強(qiáng)大捂襟,對(duì)初學(xué)者也很友好,于是抱著初生牛犢不怕虎的精神欢峰,嘗試嘗試用Python來解決一個(gè)復(fù)雜的難題葬荷。

問題

旅游愛好者小龍有錢又有時(shí)間,她決定制定一個(gè)詳盡的旅行計(jì)劃纽帖,游遍目前中國(guó)的熱門景區(qū)宠漩。目前手邊僅有的資料就是一份想要游覽的景區(qū)的名單(如下圖,總共有兩百多個(gè)景點(diǎn))懊直,其中主要是國(guó)家評(píng)定的5A級(jí)景區(qū)扒吁,制定怎樣的旅行計(jì)劃,才能最高效的游遍所有的景區(qū)呢室囊?

問題解決的思路

首先這是一個(gè)非常具有現(xiàn)實(shí)意義的問題雕崩,它的核心是旅行商問題(Traveling Salesman Problem)魁索,也就是已知地點(diǎn)和地點(diǎn)之間的距離,找出游遍所有地點(diǎn)的最短路線晨逝。這是一個(gè)計(jì)算機(jī)領(lǐng)域的NP完全問題蛾默。TSP問題的核心算法有很多人已經(jīng)研究過了。然而我們要解決的并不是一個(gè)純數(shù)學(xué)的問題捉貌,而是一個(gè)實(shí)際問題支鸡。難點(diǎn)其實(shí)在于數(shù)據(jù)的搜集和整理。
經(jīng)過一番艱難的思索和嘗試趁窃,我列出了下圖所示的程序設(shè)計(jì)思路牧挣。其主要思想在于利用百度提供的免費(fèi)API接口,獲取各個(gè)景點(diǎn)的地理位置醒陆、地址瀑构,附件機(jī)場(chǎng)、車站以及景點(diǎn)之間的路線等各種信息刨摩,再將獲得的json文件進(jìn)一步處理寺晌,得到格式化的數(shù)據(jù)往堡,導(dǎo)入TSP路徑求解器水援,獲得最優(yōu)路徑已慢,再將最優(yōu)路徑在地圖中表示出來营曼,并給出詳細(xì)的形式指南。


這是一個(gè)尚在進(jìn)行中的浩大工程雁芙,尤其對(duì)于一個(gè)Python新手來說肥照。

學(xué)習(xí)Web API的調(diào)用

Web API是一種應(yīng)用程序接口鸠信,通過一定的設(shè)置之后嚷闭,程序可以通過發(fā)送不同網(wǎng)址查詢所需的數(shù)據(jù)攒岛。API的使用需要申請(qǐng)密鑰,本文中使用的到的密鑰均可以免費(fèi)獲取胞锰。
地理服務(wù)相關(guān)的API有不少灾锯,比較成熟的是百度和谷歌兩家。雖然很多時(shí)候谷歌的服務(wù)都顯得高大上許多胜蛉,但是經(jīng)過一番嘗試挠进,在地圖服務(wù),尤其是國(guó)內(nèi)的地圖服務(wù)上誊册,百度有很多優(yōu)勢(shì)。除去連接的穩(wěn)定性之外暖璧,百度的所有Web API共享一個(gè)密鑰案怯,而谷歌需要為不同的API分別申請(qǐng)密鑰,而且百度對(duì)中文支持完善澎办,所以這里主要使用了百度地圖的Web API服務(wù)嘲碱。用戶可以到這個(gè)地址申請(qǐng):http://lbsyun.baidu.com/ 除了地圖之外金砍,百度還有一個(gè)API商店,提供了很多免費(fèi)的API服務(wù)麦锯,網(wǎng)址:http://apistore.baidu.com/

Python程序

調(diào)用Web API的程序其實(shí)相當(dāng)簡(jiǎn)單恕稠,筆者作為一個(gè)小白沒花多長(zhǎng)時(shí)間就搗鼓出了一段代碼。

# -*- coding: utf-8 -*-
'''
Created on 17-June-2016 @Jerry
用于調(diào)用百度地圖和去哪兒網(wǎng)的web api扶欣。
'''

import sys,urllib2,urllib,os

#===============================================================================
#讀取API Key--------------------------------------------
f_key = open("API Key.txt",mode='r')
key = []
for line in f_key.readlines():
    line = line.strip('\n')
    key += [line.split(",")]
apikey = dict(key)
f_key.close()
#------------------------------------------------------
#讀取API Url--------------------------------------------
f_url = open("API Url.txt",mode='r')
url = []
for line in f_url.readlines():
    line = line.strip('\n')
    url += [line.split(",")]
apiurl = dict(url)
f_url.close()
#------------------------------------------------------
#===============================================================================

#===============================================================================
#查詢百度地圖API-------------------------------------------
class BaiduQuery:
    def __init__(self,api,args,name):
        self.api = api          #調(diào)用的API名稱
        self.args = args        #查詢變量
        self.name = name        #查詢結(jié)果的命名方式

    def getjson(self):
        baseurl = apiurl[self.api]
        self.args["ak"] = apikey["BaiduMap"]
        self.args["output"] = "json"
        encodeargs = urllib.urlencode(self.args)
        url = urllib.unquote(baseurl + encodeargs)
        routeDir = "Data/"+self.name+'/'+self.api+'.json'
        urllib.urlretrieve(url, routeDir)
        print self.name,self.api," -> Success"

    def makedir(self):          #文件夾是否已創(chuàng)建
        if not os.path.exists("Data/"+self.name+"/"):
            os.makedirs('Data/'+self.name+'/')
            print "Make Dir Successfully!"
            return 1
        else:
            return 0
#------------------------------------------------------
#===============================================================================
#查詢百度API商店中去哪兒網(wǎng)火車票鹅巍、景點(diǎn)門票--------------------------------------
class QunarQuery:
    def __init__(self,api,args,name):
        self.api = api          #調(diào)用的API名稱
        self.args = args        #查詢變量
        self.name = name        #查詢結(jié)果的命名方式

    def getjson(self):
        baseurl = apiurl[self.api]
        encodeargs = urllib.urlencode(self.args)
        url = urllib.unquote(baseurl + encodeargs)
        routeDir = "Data/"+self.name+'/'+self.api+'.json'
        req = urllib2.Request(url)
        req.add_header("apikey", apikey["Qunar"])
        resp = urllib2.urlopen(req)
        content = resp.read()
        if(content):
            with open(routeDir, "wb") as code:
                code.write(content)
        print self.name,self.api," -> Success"

    def makedir(self):          #文件夾是否已創(chuàng)建
        if not os.path.exists("Data/"+self.name+"/"):
            os.makedirs('Data/'+self.name+'/')
            print self.name," -> Make Dir"
            return 1
        else:
            return 0
#------------------------------------------------------
#===============================================================================
#使用示例-----------------------------------------------
# values={
#     "version":"1.0",
#     "from":"上海",
#     "to":"南京",
#     "date":"2016-06-18"
# }
# ID23 = QunarQuery("QunarTrain",values,"23")
# ID23.makedir()
# ID23.getjson()
#===============================================================================

這段代碼將需要查詢的信息編碼到網(wǎng)址中,其中兩個(gè)本地txt文件中存放的是申請(qǐng)的API Key和各種不同的Web服務(wù)的網(wǎng)址料祠。網(wǎng)址在官網(wǎng)都可以查詢到骆捧,需要注意的是網(wǎng)址后面要手動(dòng)加上一個(gè)“?”髓绽。
由于百度地圖的API和百度API商店中的API調(diào)用略有不同敛苇,因此寫了兩個(gè)class,不知道大牛能不能將兩個(gè)class合并成一個(gè)顺呕。
在調(diào)用不同的服務(wù)的時(shí)候枫攀,輸入相關(guān)參數(shù),將返回的json文件存儲(chǔ)到本地相應(yīng)景點(diǎn)編號(hào)下的文件夾中株茶。

json文件的處理

本文中用到的API返回的都是json格式的文件(如下圖)来涨。看起來密密麻麻忌卤,作為小白的我當(dāng)然是沒聽說過這是個(gè)啥啦扫夜。一番百度之后,找到了一個(gè)很好的在線工具json在線編輯器驰徊,可以將json文件重新排版笤闯,并且給出文件結(jié)構(gòu)樹,相當(dāng)方便棍厂。


格式化之后的文件就好看了許多颗味,可以看到里面包含了兩地之間的火車票信息,這是通過qunar的接口獲得的數(shù)據(jù)牺弹。

json文件的處理筆者還沒有摸索出最優(yōu)的方法浦马,等搞清楚了再來寫一寫。

中國(guó)的景點(diǎn)分布圖

在我之前的嘗試中张漂,我試著用Python的Basemap和GeoPy包解析處理這兩百多個(gè)景點(diǎn)的具體經(jīng)緯度信息晶默,當(dāng)然后來發(fā)現(xiàn)還是百度地圖的API最直接最方便。獲取的這些數(shù)據(jù)直接繪制出來就是下面的效果航攒,圖中的深藍(lán)色小點(diǎn)就是中國(guó)5A景區(qū)所在地:



在通過flight100網(wǎng)站獲得全世界所有機(jī)場(chǎng)和航線的數(shù)據(jù)之后磺陡,我又將其中中國(guó)的數(shù)據(jù)篩選出來,繪制出了中國(guó)的機(jī)場(chǎng)和航線分布圖。



當(dāng)然用Basemap只能繪制出簡(jiǎn)單的靜態(tài)圖币他,有沒有辦法讓辛辛苦苦獲得的這些地理數(shù)據(jù)發(fā)揮更大的用處呢坞靶,當(dāng)然是可以的。

將地理數(shù)據(jù)導(dǎo)入Google Earth

輸出上蝴悉,你可以將地理位置數(shù)據(jù)導(dǎo)入到Google Earth中彰阴。只是在導(dǎo)入之前還需要一番處理。Google Earth使用的是一種特殊格式的kml文件拍冠,你可以在這個(gè)網(wǎng)站將可以在Excel中打開的csv格式文件在線轉(zhuǎn)換成kml文件尿这,然后直接拖入Google Earth軟件,谷歌地球會(huì)幫你自動(dòng)標(biāo)注出來倦微,效果就像下面這張圖妻味,里面的各個(gè)景點(diǎn)都用小圖釘標(biāo)注了出來。


為什么說這些數(shù)據(jù)能在谷歌地球中發(fā)揮更大價(jià)值呢欣福?這是因?yàn)楣雀璧厍蜃詭Я撕芏鄨D片责球。尤其是其中的Panoramio照片,能夠?qū)⒕包c(diǎn)周邊的真實(shí)面貌以高清照片的形式展現(xiàn)出來拓劝,讓你提前預(yù)覽美景之后雏逾,再?zèng)Q定要不要前往。

未完待續(xù)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末郑临,一起剝皮案震驚了整個(gè)濱河市栖博,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌厢洞,老刑警劉巖仇让,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異躺翻,居然都是意外死亡丧叽,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門公你,熙熙樓的掌柜王于貴愁眉苦臉地迎上來踊淳,“玉大人,你說我怎么就攤上這事陕靠∮爻ⅲ” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵剪芥,是天一觀的道長(zhǎng)垄开。 經(jīng)常有香客問我,道長(zhǎng)税肪,這世上最難降的妖魔是什么说榆? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任虚吟,我火速辦了婚禮寸认,結(jié)果婚禮上签财,老公的妹妹穿的比我還像新娘。我一直安慰自己偏塞,他們只是感情好唱蒸,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著灸叼,像睡著了一般神汹。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上古今,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天屁魏,我揣著相機(jī)與錄音,去河邊找鬼捉腥。 笑死氓拼,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的抵碟。 我是一名探鬼主播桃漾,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼拟逮!你這毒婦竟也來了撬统?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤敦迄,失蹤者是張志新(化名)和其女友劉穎恋追,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體罚屋,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡苦囱,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了沿后。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片沿彭。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖尖滚,靈堂內(nèi)的尸體忽然破棺而出喉刘,到底是詐尸還是另有隱情,我是刑警寧澤漆弄,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布睦裳,位于F島的核電站,受9級(jí)特大地震影響撼唾,放射性物質(zhì)發(fā)生泄漏廉邑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蛛蒙。 院中可真熱鬧糙箍,春花似錦、人聲如沸牵祟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)诺苹。三九已至咕晋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間收奔,已是汗流浹背掌呜。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留坪哄,地道東北人质蕉。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像损姜,于是被迫代替她去往敵國(guó)和親饰剥。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容