
于是我萌生了通過(guò)旅游網(wǎng)站的景點(diǎn)銷量來(lái)判斷近期各景點(diǎn)流量情況的想法(這個(gè)想法很危險(xiǎn)啊)。
所以這次的目標(biāo)呢,是爬去哪兒網(wǎng)景點(diǎn)頁(yè)面,并得到景點(diǎn)的信息,大家可以先思考下大概需要幾步。

因?yàn)榍皫状闻老x都是爬一些文本信息,做一下詞云之類的,我覺(jué)得:沒(méi)!意!思!了!這次正好爬的是數(shù)據(jù),我決定用數(shù)據(jù)的好基友——圖表來(lái)輸出我爬取的數(shù)據(jù),也就是說(shuō)我要用爬取的景點(diǎn)銷量以及景點(diǎn)的具體位置來(lái)生成一些可視化數(shù)據(jù)。
安利一下百度的地圖 API 和 echarts,前者是專門提供地圖 API 的工具,聽說(shuō)好多 APP 都在用它,后者是數(shù)據(jù)處理居家旅行的好伙伴,用了之后,它好,我也好(隱約覺(jué)得哪里不對(duì))。
API 是什么,API 是應(yīng)用程序的編程接口,就好像插頭與插座一樣,我們的程序需要電(這是什么程序?),插座中提供了電,我們只需要在程序中寫一個(gè)與插座匹配的插頭接口,就可以使用電來(lái)做我們想做的事情,而不需要知道電是如何產(chǎn)生的。

有人可能說(shuō),我已經(jīng)懂了 API 是啥意思了,可是咋個(gè)用呢。關(guān)于這一點(diǎn),我很負(fù)責(zé)任的告訴你:我也不會(huì)。
但是!百度地圖提供了很多 API 使用示例,有 html 基礎(chǔ),大致可以看懂,有 js 基礎(chǔ)就可以嘗試改函數(shù)了(不會(huì) js 的,我默默地復(fù)制源代碼),仔細(xì)觀察源代碼,可以知道熱力圖生成的主要數(shù)據(jù)都存放在 points 這個(gè)變量中。
這種[{x:x,x:x},{x:x,x:x}]格式的數(shù)據(jù),是一種 json 格式的數(shù)據(jù),由于具有自我描述性,所以比較通俗易懂,大概可以知道這里的三個(gè)值,前兩個(gè)是經(jīng)緯度,最后一個(gè)應(yīng)該是權(quán)重(我猜的)。
也就是說(shuō),如果我希望將景點(diǎn)的熱門程度生成為熱力圖,我需要得到景點(diǎn)的經(jīng)緯度,以及它的權(quán)重,景點(diǎn)的銷量可以作為權(quán)重,并且這個(gè)數(shù)據(jù)應(yīng)該是 json 格式的呈現(xiàn)方式。
echarts 也是一樣滴(*^__^*)。
爬取數(shù)據(jù)
這次的爬蟲部分是比較簡(jiǎn)單的。分析網(wǎng)址(去哪兒景點(diǎn))→爬取分頁(yè)中信息(景點(diǎn)經(jīng)緯度、銷量)→轉(zhuǎn)為 json 文件。
分析去哪兒景點(diǎn)頁(yè)的網(wǎng)址,可得出結(jié)構(gòu):http://piao.qunar.com/ticket/list.htm?keyword=搜索地點(diǎn)®ion=&from=mpl_search_suggest&page=頁(yè)數(shù)
這次沒(méi)有用正則來(lái)匹配內(nèi)容,而使用了 xpath 匹配,非常好用。
-
這里把每個(gè)景點(diǎn)的所有信息都爬下來(lái)了(其實(shí)是為了練習(xí)使用 xpath……)。
-
使用了 while 循環(huán),for 循環(huán)的 break 的方式是發(fā)現(xiàn)無(wú)銷量時(shí)給 i 值賦零,這樣 while 循環(huán)也會(huì)同時(shí)結(jié)束。
-
地址的匹配使用 re.sub() 函數(shù)去除了 n 多復(fù)雜信息,這點(diǎn)后面解釋。
輸出本地文本
為了防止代碼運(yùn)行錯(cuò)誤,維護(hù)代碼運(yùn)行的和平,將輸出的信息列表存入到 excel 文件中了,方便日后查閱,很簡(jiǎn)單的代碼,需要了解 pandas 的用法。



在設(shè)置獲取經(jīng)緯度的地址時(shí),為了匹配到更準(zhǔn)確的經(jīng)緯度,我選擇了匹配景點(diǎn)地址,然而,景點(diǎn)地址里有各種神奇的地址,帶括號(hào)解釋在 XX 對(duì)面的,說(shuō)一堆你應(yīng)該左拐右拐各種拐就能到的,還有英文的……
于是就有了第三章中復(fù)雜的去除信息(我終于圓回來(lái)了!)。
然而,就算去掉了復(fù)雜信息,還有一些匹配不到的景點(diǎn)地址,于是我使用了嵌套 try,如果景點(diǎn)地址匹配不到;就匹配景點(diǎn)名稱,如果景點(diǎn)名稱匹配不到;就匹配景點(diǎn)所在區(qū)域,如果依然匹配不到,那我……那我就……那我就跳過(guò)ㄒ_ㄒ……
身為一個(gè)景點(diǎn),你怎么能,這么難找呢!不要你了!
這里生成的三個(gè) json 文件,一個(gè)是給百度地圖 API 引入用的,另兩個(gè)是給 echarts 引入用的。
網(wǎng)頁(yè)讀取 json 文件
將第二章中所述的百度地圖 API 示例中的源代碼復(fù)制到解釋器中,添加密鑰,保存為 html 文件,打開就可以看到和官網(wǎng)上一樣的顯示效果。
echarts 需要在實(shí)例頁(yè)面,點(diǎn)擊頁(yè)面右上角的 EN 切換到英文版,然后點(diǎn)擊 download demo 下載完整源代碼。
根據(jù) html 導(dǎo)入 json 文件修改網(wǎng)頁(yè)源碼,導(dǎo)入 json 文件。
這里使用了 jQuery 之后,即使網(wǎng)頁(yè)調(diào)試成功了,在本地打開也無(wú)法顯示網(wǎng)頁(yè)了,在 chrome 中右鍵檢查,發(fā)現(xiàn)報(bào)錯(cuò)提示是需要在服務(wù)器上顯示,可是,服務(wù)器是什么呢?
百度了一下,可以在本地創(chuàng)建一個(gè)服務(wù)器,在終端進(jìn)入到 html 文件所在文件夾,輸入python -m SimpleHTTPServer,再在瀏覽器中打開 http://127.0.0.1:8000/,記得要將 html 文件名設(shè)置成 index.html 哦!
后記
因?yàn)樽?cè)但沒(méi)有認(rèn)證開發(fā)者賬號(hào),所以每天只能獲取 6K 個(gè)經(jīng)緯度 API(這是一個(gè)很好的偷懶理由),所以我選擇了熱門景點(diǎn)中前 400 頁(yè)(每頁(yè) 15 個(gè))的景點(diǎn)。
結(jié)果可想而知,(?﹏?)為了調(diào)試因?yàn)閿?shù)據(jù)增多出現(xiàn)的額外 Bug,最終的獲取的景點(diǎn)數(shù)據(jù)大概在 4500 條左右(爬取時(shí)間為 2017 年 9 月 10 日,爬取關(guān)鍵詞:熱門景點(diǎn),僅代表當(dāng)時(shí)銷量)。

將地圖上熱門景點(diǎn)的銷量 Top20 提取出來(lái),大多數(shù)都是耳熟能詳?shù)牡攸c(diǎn),帝都的故宮排在了第一位,而大四川則占據(jù)了 Top5 中的三位,排在 Top20 中四川省景點(diǎn)就占了 6 位。
如果不是因?yàn)榈卣穑蚁脒€會(huì)有更多的火爆的景點(diǎn)進(jìn)入排行榜的~這樣看來(lái)如果你這次國(guó)慶打算去四川的話,可以腦補(bǔ)到的場(chǎng)景就是:人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人……
熱門景點(diǎn)銷量Top20
于是我又做了一個(gè)各城市包含熱門景點(diǎn)數(shù)目的排行,沒(méi)想到在 4 千多個(gè)熱門景點(diǎn)中,數(shù)目最多的竟是我大浙江,是第二個(gè)城市的 1.5 倍,而北京作為首都也……可以說(shuō)是景點(diǎn)數(shù)/總面積的第一位了。
主要城市熱門景點(diǎn)數(shù)
這些城市有辣么多熱門景點(diǎn),都是些什么級(jí)別的景點(diǎn)呢?由下圖看來(lái),各城市的各級(jí)別景點(diǎn)基本與城市總熱門景點(diǎn)呈正相關(guān),而且主要由 4A 景區(qū)貢獻(xiàn)而來(lái)。
主要城市熱門景點(diǎn)級(jí)別
既然去哪些地方人多,去哪里景多都已經(jīng)知道了,那再看看去哪些地方燒得錢最多吧。
下圖是由各城市景點(diǎn)銷售起步價(jià)的最大值-最小值扇形組成的圓,其中湖北以單景點(diǎn)銷售起步價(jià) 600 占據(jù)首位。
但也可以看到,湖北的景點(diǎn)銷售均價(jià)并不高(在紅色扇形中的藏藍(lán)色線條)。而如果國(guó)慶去香港玩,請(qǐng)做好錢包減肥的心理和生理準(zhǔn)備(•?ω•?)?。
各省旅游景點(diǎn)銷售起步價(jià)
好啦分析完啦,ヾ(*ΦωΦ)ツ大家可要好好玩呀。