成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

我用Python爬取了全國4500個熱門景點,告訴你國慶哪兒最堵?

開發 后端
金秋九月,丹桂飄香,在這秋高氣爽,陽光燦爛的收獲季節里,我們送走了一個個暑假余額耗盡哭著走向校園的孩子們,又即將迎來一年一度偉大祖國母親的生日趴體(無心上班,迫不及待想為祖國母親慶生)。

[[203795]]

金秋九月,丹桂飄香,在這秋高氣爽,陽光燦爛的收獲季節里,我們送走了一個個暑假余額耗盡哭著走向校園的孩子們,又即將迎來一年一度偉大祖國母親的生日趴體(無心上班,迫不及待想為祖國母親慶生)。

[[203796]]

那么問題來了,去哪兒玩呢?百度輸了個“國慶”,出來的第一條居然是“去哪里旅游人少”……emmmmmmm,因缺思廳。

于是我萌生了通過旅游網站的景點銷量來判斷近期各景點流量情況的想法(這個想法很危險啊)。

所以這次的目標呢,是爬去哪兒網景點頁面,并得到景點的信息,大家可以先思考下大概需要幾步。

本文建議有一定 Python 基礎和前端(html,js)基礎的朋友閱讀,零基礎可以去看我之前的文。(咳咳,不能總更小白文,這樣顯得我不(mei)夠(you)專(xue)業(xi))。

百度的地圖 API 和 echarts

因為前幾次爬蟲都是爬一些文本信息,做一下詞云之類的,我覺得:沒!意!思!了!這次正好爬的是數據,我決定用數據的好基友——圖表來輸出我爬取的數據,也就是說我要用爬取的景點銷量以及景點的具體位置來生成一些可視化數據。

安利一下百度的地圖 API 和 echarts,前者是專門提供地圖 API 的工具,聽說好多 APP 都在用它,后者是數據處理居家旅行的好伙伴,用了之后,它好,我也好(隱約覺得哪里不對)。

API 是什么,API 是應用程序的編程接口,就好像插頭與插座一樣,我們的程序需要電(這是什么程序?),插座中提供了電,我們只需要在程序中寫一個與插座匹配的插頭接口,就可以使用電來做我們想做的事情,而不需要知道電是如何產生的。

引入數據后的百度熱力圖

通過 API 對接的開發者與服務商

確定輸出文件

有人可能說,我已經懂了 API 是啥意思了,可是咋個用呢。關于這一點,我很負責任的告訴你:我也不會。

但是!百度地圖提供了很多 API 使用示例,有 html 基礎,大致可以看懂,有 js 基礎就可以嘗試改函數了(不會 js 的,我默默地復制源代碼),仔細觀察源代碼,可以知道熱力圖生成的主要數據都存放在 points 這個變量中。

這種[{x:x,x:x},{x:x,x:x}]格式的數據,是一種 json 格式的數據,由于具有自我描述性,所以比較通俗易懂,大概可以知道這里的三個值,前兩個是經緯度,最后一個應該是權重(我猜的)。

也就是說,如果我希望將景點的熱門程度生成為熱力圖,我需要得到景點的經緯度,以及它的權重,景點的銷量可以作為權重,并且這個數據應該是 json 格式的呈現方式。

echarts 也是一樣滴(*^__^*)。

爬取數據

這次的爬蟲部分是比較簡單的。分析網址(去哪兒景點)→爬取分頁中信息(景點經緯度、銷量)→轉為 json 文件。

分析去哪兒景點頁的網址,可得出結構:http://piao.qunar.com/ticket/list.htm?keyword=搜索地點®ion=&from=mpl_search_suggest&page=頁數

這次沒有用正則來匹配內容,而使用了 xpath 匹配,非常好用。

  1. def getList(): 
  2.     place = raw_input('請輸入想搜索的區域、類型(如北京、熱門景點等):'
  3.     url = 'http://piao.qunar.com/ticket/list.htm?keyword='+ str(place) +'&region=&from=mpl_search_suggest&page={}' 
  4.     i = 1 
  5.     sightlist = [] 
  6.     while i: 
  7.         page = getPage(url.format(i)) 
  8.         selector = etree.HTML(page) 
  9.         print '正在爬取第' + str(i) + '頁景點信息' 
  10.         i+=1 
  11.         informations = selector.xpath('//div[@class="result_list"]/div'
  12.         for inf in informations: #獲取必要信息 
  13.             sight_name = inf.xpath('./div/div/h3/a/text()')[0] 
  14.             sight_level = inf.xpath('.//span[@class="level"]/text()'
  15.             if len(sight_level): 
  16.                 sight_level = sight_level[0].replace('景區',''
  17.             else
  18.                 sight_level = 0 
  19.             sight_area = inf.xpath('.//span[@class="area"]/a/text()')[0] 
  20.             sight_hot = inf.xpath('.//span[@class="product_star_level"]//span/text()')[0].replace('熱度 ',''
  21.             sight_add = inf.xpath('.//p[@class="address color999"]/span/text()')[0] 
  22.             sight_add = re.sub('地址:|(.*?)|\(.*?\)|,.*?$|\/.*?$','',str(sight_add)) 
  23.             sight_slogen = inf.xpath('.//div[@class="intro color999"]/text()')[0] 
  24.             sight_price = inf.xpath('.//span[@class="sight_item_price"]/em/text()'
  25.             if len(sight_price): 
  26.                 sight_price = sight_price[0] 
  27.             else
  28.                 i = 0 
  29.                 break 
  30.             sight_soldnum = inf.xpath('.//span[@class="hot_num"]/text()')[0] 
  31.             sight_url = inf.xpath('.//h3/a[@class="name"]/@href')[0] 
  32.             sightlist.append([sight_name,sight_level,sight_area,float(sight_price),int(sight_soldnum),float(sight_hot),sight_add.replace('地址:',''),sight_slogen,sight_url]) 
  33.         time.sleep(3) 
  34.     return sightlist,place 
  • 這里把每個景點的所有信息都爬下來了(其實是為了練習使用 xpath……)。
  • 使用了 while 循環,for 循環的 break 的方式是發現無銷量時給 i 值賦零,這樣 while 循環也會同時結束。
  • 地址的匹配使用 re.sub() 函數去除了 n 多復雜信息,這點后面解釋。

輸出本地文本

為了防止代碼運行錯誤,維護代碼運行的和平,將輸出的信息列表存入到 excel 文件中了,方便日后查閱,很簡單的代碼,需要了解 pandas 的用法。

  1. def listToExcel(list,name): 
  2.     df = pd.DataFrame(list,columns=['景點名稱','級別','所在區域','起步價','銷售量','熱度','地址','標語','詳情網址']) 
  3.     df.to_excel(name + '景點信息.xlsx'

百度經緯度 API

非常悲傷的,(ಥ﹏ಥ)我沒找到去哪兒景點的經緯度,以為這次學(zhuang)習(bi)計劃要就此流產了。(如果有人知道景點經緯度在哪里請告訴我)

但是,enhahhahahaha,我怎么會放棄呢,我又找到了百度經緯度 API。

網址:http://api.map.baidu.com/geocoder/v2/?address=地址&output=json&ak=百度密鑰,修改網址里的“地址”和“百度密鑰”,在瀏覽器打開,就可以看到經緯度的 json 信息。

  1. #上海市東方明珠的經緯度信息 
  2. {"status":0,"result":{"location":{"lng":121.5064701060957,"lat":31.245341811634675},"precise":1,"confidence":70,"level":"UNKNOWN"}} 

百度密鑰申請方法:http://jingyan.baidu.com/article/363872eccda8286e4aa16f4e.html

這樣我就可以根據爬到的景點地址,查到對應的經緯度辣!Python 獲取經緯度 json 數據的代碼如下:

  1. def getBaiduGeo(sightlist,name): 
  2.     ak = '密鑰' 
  3.     headers = { 
  4.     'User-Agent' :'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36' 
  5.     } 
  6.     address = 地址 
  7.     url = 'http://api.map.baidu.com/geocoder/v2/?address=' + address  + '&output=json&ak=' + ak 
  8.     json_data = requests.get(url = url).json() 
  9.     json_geo = json_data['result']['location'

觀察獲取的 json 文件,location 中的數據和百度 API 所需要的 json 格式基本是一樣,還需要將景點銷量加入到 json 文件中,這里可以了解一下 json 的淺拷貝和深拷貝知識,最后將整理好的 json 文件輸出到本地文件中。

  1. def getBaiduGeo(sightlist,name): 
  2.     ak = '密鑰' 
  3.     headers = { 
  4.     'User-Agent' :'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36' 
  5.     } 
  6.     list = sightlist 
  7.     bjsonlist = [] 
  8.     ejsonlist1 = [] 
  9.     ejsonlist2 = [] 
  10.     num = 1 
  11.     for l in list: 
  12.         try: 
  13.             try: 
  14.                 try: 
  15.                     address = l[6] 
  16.                     url = 'http://api.map.baidu.com/geocoder/v2/?address=' + address  + '&output=json&ak=' + ak 
  17.                     json_data = requests.get(url = url).json() 
  18.                     json_geo = json_data['result']['location'
  19.                 except KeyError,e: 
  20.                     address = l[0] 
  21.                     url = 'http://api.map.baidu.com/geocoder/v2/?address=' + address  + '&output=json&ak=' + ak 
  22.                     json_data = requests.get(url = url).json() 
  23.                     json_geo = json_data['result']['location'
  24.             except KeyError,e: 
  25.                     address = l[2] 
  26.                     url = 'http://api.map.baidu.com/geocoder/v2/?address=' + address  + '&output=json&ak=' + ak 
  27.                     json_data = requests.get(url = url).json() 
  28.                     json_geo = json_data['result']['location'
  29.         except KeyError,e: 
  30.             continue 
  31.         json_geo['count'] = l[4]/100 
  32.         bjsonlist.append(json_geo) 
  33.         ejson1 = {l[0] : [json_geo['lng'],json_geo['lat']]} 
  34.         ejsonlist1 = dict(ejsonlist1,**ejson1) 
  35.         ejson2 = {'name' : l[0],'value' : l[4]/100} 
  36.         ejsonlist2.append(ejson2) 
  37.         print '正在生成第' + str(num) + '個景點的經緯度' 
  38.         num +=1 
  39.     bjsonlist =json.dumps(bjsonlist) 
  40.     ejsonlist1 = json.dumps(ejsonlist1,ensure_ascii=False
  41.     ejsonlist2 = json.dumps(ejsonlist2,ensure_ascii=False
  42.     with open('./points.json',"w"as f: 
  43.         f.write(bjsonlist) 
  44.     with open('./geoCoordMap.json',"w"as f: 
  45.         f.write(ejsonlist1) 
  46.     with open('./data.json',"w"as f: 
  47.         f.write(ejsonlist2) 

在設置獲取經緯度的地址時,為了匹配到更準確的經緯度,我選擇了匹配景點地址,然而,景點地址里有各種神奇的地址,帶括號解釋在 XX 對面的,說一堆你應該左拐右拐各種拐就能到的,還有英文的……

于是就有了第三章中復雜的去除信息(我終于圓回來了!)。

然而,就算去掉了復雜信息,還有一些匹配不到的景點地址,于是我使用了嵌套 try,如果景點地址匹配不到;就匹配景點名稱,如果景點名稱匹配不到;就匹配景點所在區域,如果依然匹配不到,那我……那我就……那我就跳過ㄒ_ㄒ……

身為一個景點,你怎么能,這么難找呢!不要你了!

這里生成的三個 json 文件,一個是給百度地圖 API 引入用的,另兩個是給 echarts 引入用的。

網頁讀取 json 文件

將第二章中所述的百度地圖 API 示例中的源代碼復制到解釋器中,添加密鑰,保存為 html 文件,打開就可以看到和官網上一樣的顯示效果。

echarts 需要在實例頁面,點擊頁面右上角的 EN 切換到英文版,然后點擊 download demo 下載完整源代碼。

根據 html 導入 json 文件修改網頁源碼,導入 json 文件。

  1. #百度地圖api示例代碼中各位置修改部分 
  2. <head> 
  3.     <script src="http://libs.baidu.com/jquery/2.0.0/jquery.js"></script> 
  4. </head> 
  5. <script type="text/javascript"
  6.     $.getJSON("points.json"function(data){ 
  7.         var points = data; 
  8.         script中原有函數; 
  9.         }); 
  10. </script> 

這里使用了 jQuery 之后,即使網頁調試成功了,在本地打開也無法顯示網頁了,在 chrome 中右鍵檢查,發現報錯提示是需要在服務器上顯示,可是,服務器是什么呢?

[[203800]]

百度了一下,可以在本地創建一個服務器,在終端進入到 html 文件所在文件夾,輸入 python -m SimpleHTTPServer,再在瀏覽器中打開 http://127.0.0.1:8000/,記得要將 html 文件名設置成 index.html 哦!

 

后記

因為注冊但沒有認證開發者賬號,所以每天只能獲取 6K 個經緯度 API(這是一個很好的偷懶理由),所以我選擇了熱門景點中前 400 頁(每頁 15 個)的景點。

結果可想而知,(ಥ﹏ಥ)為了調試因為數據增多出現的額外 Bug,最終的獲取的景點數據大概在 4500 條左右(爬取時間為 2017 年 9 月 10 日,爬取關鍵詞:熱門景點,僅代表當時銷量)。

熱門景點熱力圖

熱門景點示意圖

這些地圖上很火爆的區域,我想在國慶大概是這樣的

[[203803]]

這樣的

[[203804]]

還有這樣的

[[203805]]

將地圖上熱門景點的銷量 Top20 提取出來,大多數都是耳熟能詳的地點,帝都的故宮排在了第一位,而大四川則占據了 Top5 中的三位,排在 Top20 中四川省景點就占了 6 位。

如果不是因為地震,我想還會有更多的火爆的景點進入排行榜的~這樣看來如果你這次國慶打算去四川的話,可以腦補到的場景就是:人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人……

熱門景點銷量Top20

于是我又做了一個各城市包含熱門景點數目的排行,沒想到在 4 千多個熱門景點中,數目最多的竟是我大浙江,是第二個城市的 1.5 倍,而北京作為首都也……可以說是景點數/總面積的第一位了。

主要城市熱門景點數

這些城市有辣么多熱門景點,都是些什么級別的景點呢?由下圖看來,各城市的各級別景點基本與城市總熱門景點呈正相關,而且主要由 4A 景區貢獻而來。

主要城市熱門景點級別

既然去哪些地方人多,去哪里景多都已經知道了,那再看看去哪些地方燒得錢最多吧。

下圖是由各城市景點銷售起步價的最大值-最小值扇形組成的圓,其中湖北以單景點銷售起步價 600 占據首位。

但也可以看到,湖北的景點銷售均價并不高(在紅色扇形中的藏藍色線條)。而如果國慶去香港玩,請做好錢包減肥的心理和生理準備(•̀ω•́)✧。

各省旅游景點銷售起步價

好啦分析完啦,ヾ(*ΦωΦ)ツ大家可要好好玩呀。

PS:寫了個網頁,展示百度地圖的熱力圖效果和 echarts 的景點排行榜,方便大家查看。

熱力度效果:http://easyinfo.online

gayhub源碼:https://github.com/otakurice/notravellist/tree/master

寫完這篇文的時候發現 echarts 有針對 Python 的模塊可以引入,所以打算去學一下 Django、Flask 之類的 Web 框架,最近會更一些純理論的意識流文,大家一起進步吧~

參考資料:

1.地圖API:http://developer.baidu.com/map/reference/index.php

2.echarts:http://echarts.baidu.com/

3.API使用示例:http://developer.baidu.com/map/jsdemo.htm#c1_15

4.json:http://www.runoob.com/json/json-tutorial.html

5.xpath:http://www.runoob.com/xpath/xpath-tutorial.html

6.pandas:http://python.jobbole.com/84416/

7.百度經緯度api:http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-geocoding

8.淺拷貝和深拷貝:http://python.jobbole.com/82294/

9.html導入json文件:http://www.jb51.net/article/36678.htm

最后,懷著敬畏又惋惜的心情紀念一下 WePhone 創始人蘇享茂,在發生自殺事件之前我不認識他,我也不希望以這種方式認識他,希望程序員的世界永遠單純、沒有欺詐。

責任編輯:武曉燕 來源: 51CTO技術棧
相關推薦

2017-09-29 09:29:32

架構技術棧微信半月刊

2019-09-29 08:50:01

Python IT旅游

2018-11-28 10:23:01

Python旅游景點數據

2021-09-06 11:57:30

Python

2021-04-27 09:33:41

Python北京景點

2019-09-29 10:00:46

Python程序員旅游

2018-08-15 08:52:49

爬蟲出行城市數據

2020-12-31 10:24:37

Python元旦旅游代碼

2017-11-27 10:18:57

Python短評sleep

2017-08-21 10:05:57

Python影評 爬蟲

2019-05-05 09:14:19

數據.

2018-09-19 14:03:00

Python房價cookie

2015-02-03 14:28:43

騰訊投資團隊

2019-06-04 08:45:00

點贊APP設計

2018-11-06 13:24:27

爬蟲分析房租

2020-10-09 15:29:48

大數據國慶技術

2019-08-28 16:22:30

Python數據微信

2020-07-14 10:19:29

Python 開發運維

2018-03-07 17:47:16

藍屏計算機死機

2020-12-30 09:18:46

JVM內部信息
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产探花在线精品一区二区 | 国产精品污www一区二区三区 | 中文字幕一区二区三区四区五区 | 成人国产精品色哟哟 | 在线亚洲免费 | 国产精品视频入口 | 91精品国产91久久久久久最新 | 欧美激情视频网站 | 成人免费在线小视频 | 精品人伦一区二区三区蜜桃网站 | 欧美亚州 | 国产日韩欧美在线观看 | 亚洲成人精品在线观看 | 成人精品视频 | 成年人在线观看 | 国产福利91精品一区二区三区 | 国产精品1区2区 | 欧美久久久久久久 | 精品国产一区二区三区免费 | 日韩在线精品视频 | 国产美女h视频 | 天堂av在线影院 | 91久久国产综合久久 | 亚州精品天堂中文字幕 | 中文字幕第十五页 | 亚洲视频在线观看 | 免费在线观看成人av | 神马久久香蕉 | 中国一级特黄真人毛片免费观看 | 久久亚洲美女 | 91久久国产综合久久91精品网站 | 黄色一级片在线播放 | 国产精品视频一二三区 | 一区二区三区四区毛片 | 色av一区 | 精品一二三 | 青青艹在线视频 | 91视频18| 亚洲高清一区二区三区 | 欧美一级黄色片在线观看 | 亚洲视频免费观看 |