用Python爬蟲爬取去哪兒4500個熱門景點,看看國慶不能去哪兒

2021-02-19 Python愛好者社區

作者:大吉大利小米醬

Python愛好者社區專欄作者   機械工程師/偽程序媛/18線靈魂畫手/段子手/腦洞女王  python交友娛樂會所:613176398

簡書:http://www.jianshu.com/u/8e45f2f3b6c1
知乎:https://www.zhihu.com/people/otakurice

前言:本文建議有一定Python基礎和前端(html,js)基礎的盆友閱讀。

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

那麼問題來了,去哪兒玩呢?百度輸了個「國慶」,出來的第一條居然是「去哪裡旅遊人少」……emmmmmmm,因缺思廳。

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

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

1.百度的地圖API和echarts

這次正好爬的是數據,我決定用數據的好基友——圖表來輸出我爬取的數據,也就是說我要用爬取的景點銷量以及景點的具體位置來生成一些可視化數據。

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

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

再詳細一點講呢,就好比米醬的小說寫完啦!但她還想把小說出成書,可是怎麼出書捏?米醬不會呀,這時候米醬發現某出版社提供了出版服務,出版社表示只需要提供小說的正文、以及一個設計的封面就可以啦,於是米醬將小說保存成了word格式,又畫了個封面jpg圖,發給了出版社,沒過多久米醬就拿到了一本裝訂好的書啦(此段純屬虛構,專業出版人士儘管打我,我不會承認的)。

在米醬出書的過程中,米醬並不需要知道出版社是怎麼印刷這個書的,也不需要知道是怎麼裝訂這個書的,米醬只需要提供出版社所要求的東西即可。

2.確定輸出文件

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

但是!

百度地圖提供了很多API使用示例,http://developer.baidu.com/map/jsdemo.htm#c1_15

有html基礎,大致可以看懂,有js基礎就可以嘗試改函數了(不會jsの我默默地複製原始碼),仔細觀察原始碼,可以知道熱力圖的生成主要的數據都存放在points這個變量中。

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

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

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

3.爬取數據

其實這次的爬虫部分是比較簡單的(如果你有跟著我的文爬過網站的話)。

分析網址(去哪兒景點)→爬取分頁中信息(景點經緯度、銷量)→轉為json文件。

分析去哪兒景點頁的網址可得出結構:

http://piao.qunar.com/ticket/list.htm?keyword=搜索地點&region=&from=mpl_search_suggest&page=頁數

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

def getList():    place = raw_input('請輸入想搜索的區域、類型(如北京、熱門景點等):')    url = 'http://piao.qunar.com/ticket/list.htm?keyword='+ str(place) +'&region=&from=mpl_search_suggest&page={}'    i = 1    sightlist = []    while i:        page = getPage(url.format(i))        selector = etree.HTML(page)        print '正在爬取第' + str(i) + '頁景點信息'        i+=1        informations = selector.xpath('//div[@class="result_list"]/div')        for inf in informations: #獲取必要信息            sight_name = inf.xpath('./div/div/h3/a/text()')[0]            sight_level = inf.xpath('.//span[@class="level"]/text()')            if len(sight_level):                sight_level = sight_level[0].replace('景區','')            else:                sight_level = 0            sight_area = inf.xpath('.//span[@class="area"]/a/text()')[0]            sight_hot = inf.xpath('.//span[@class="product_star_level"]//span/text()')[0].replace('熱度 ','')            sight_add = inf.xpath('.//p[@class="address color999"]/span/text()')[0]            sight_add = re.sub('地址:|(.*?)|\(.*?\)|,.*?$|\/.*?$','',str(sight_add))            sight_slogen = inf.xpath('.//div[@class="intro color999"]/text()')[0]            sight_price = inf.xpath('.//span[@class="sight_item_price"]/em/text()')            if len(sight_price):                sight_price = sight_price[0]            else:                i = 0                break            sight_soldnum = inf.xpath('.//span[@class="hot_num"]/text()')[0]            sight_url = inf.xpath('.//h3/a[@class="name"]/@href')[0]            sightlist.append([sight_name,sight_level,sight_area,float(sight_price),int(sight_soldnum),float(sight_hot),sight_add.replace('地址:',''),sight_slogen,sight_url])        time.sleep(3)    return sightlist,place

1.這裡把每個景點的所有信息都爬下來了(其實是為了練習使用xpath……)。 
2.使用了while循環,for循環的break的方式是發現無銷量時給i值賦零,這樣while循環也會同時結束。 
3.地址的匹配使用re.sub()函數去除了n多複雜信息,這點後面解釋。

4.輸出本地文本

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

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

5.百度經緯度api

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

但是,enhahhahahaha,我怎麼會放棄呢,我又找到了百度經緯度api,網址:http://api.map.baidu.com/geocoder/v2/?address=地址&output=json&ak=百度密鑰,修改網址裡的「地址」和「百度密鑰」,在瀏覽器打開,就可以看到經緯度的json信息。

#上海市東方明珠的經緯度信息{"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數據的代碼如下。

def getBaiduGeo(sightlist,name):    ak = '密鑰'    headers = {    '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'    }    address = 地址    url = 'http://api.map.baidu.com/geocoder/v2/?address=' + address  + '&output=json&ak=' + ak    json_data = requests.get(url = url).json()    json_geo = json_data['result']['location']

觀察獲取的json文件,location中的數據和百度api所需要的json格式基本是一樣,還需要將景點銷量加入到json文件中,這裡可以了解一下json的淺拷貝和深拷貝知識,http://python.jobbole.com/82294/

最後將整理好的json文件輸出到本地文件中。

def getBaiduGeo(sightlist,name):    ak = '密鑰'    headers = {    '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'    }    list = sightlist    bjsonlist = []    ejsonlist1 = []    ejsonlist2 = []    num = 1    for l in list:        try:            try:                try:                    address = l[6]                    url = 'http://api.map.baidu.com/geocoder/v2/?address=' + address  + '&output=json&ak=' + ak                    json_data = requests.get(url = url).json()                    json_geo = json_data['result']['location']                except KeyError,e:                    address = l[0]                    url = 'http://api.map.baidu.com/geocoder/v2/?address=' + address  + '&output=json&ak=' + ak                    json_data = requests.get(url = url).json()                    json_geo = json_data['result']['location']            except KeyError,e:                    address = l[2]                    url = 'http://api.map.baidu.com/geocoder/v2/?address=' + address  + '&output=json&ak=' + ak                    json_data = requests.get(url = url).json()                    json_geo = json_data['result']['location']        except KeyError,e:            continue        json_geo['count'] = l[4]/100        bjsonlist.append(json_geo)        ejson1 = {l[0] : [json_geo['lng'],json_geo['lat']]}        ejsonlist1 = dict(ejsonlist1,**ejson1)        ejson2 = {'name' : l[0],'value' : l[4]/100}        ejsonlist2.append(ejson2)        print '正在生成第' + str(num) + '個景點的經緯度'        num +=1    bjsonlist =json.dumps(bjsonlist)    ejsonlist1 = json.dumps(ejsonlist1,ensure_ascii=False)    ejsonlist2 = json.dumps(ejsonlist2,ensure_ascii=False)    with open('./points.json',"w") as f:        f.write(bjsonlist)    with open('./geoCoordMap.json',"w") as f:        f.write(ejsonlist1)    with open('./data.json',"w") as f:        f.write(ejsonlist2)

(╯』 - 『)╯┻━┻

在設置獲取經緯度的地址時,為了匹配到更準確的經緯度,我選擇了匹配景點地址,然鵝,景點地址裡有各種神奇的地址,帶括號解釋在XX對面的,說一堆你應該左拐右拐各種拐就能到的,還有英文的……於是就有了第三章中複雜的去除信息(我終於圓回來了!)。

然鵝,就算去掉了複雜信息,還有一些匹配不到的景點地址,於是我使用了嵌套try,如果景點地址匹配不到;就匹配景點名稱,如果景點名稱匹配不到;就匹配景點所在區域,如果依然匹配不到,那我……那我就……那我就跳過ㄒ_ㄒ……身為一個景點,你怎麼能,這麼難找呢!不要你了!

這裡生成的三個json文件,一個是給百度地圖api引入用的,另倆個是給echarts引入用的。

6.網頁讀取json文件

將第二章中所述的百度地圖api示例中的原始碼複製到解釋器中,添加密鑰,保存為html文件,打開就可以看到和官網上一樣的顯示效果。echarts需要在實例頁面,點擊頁面右上角的EN切換到英文版,然後點擊download demo下載完整原始碼。

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

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

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

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

7.後記

因為註冊但沒有認證開發者帳號,所以每天只能獲取6K個經緯度api(這是一個很好的偷懶理由),所以我選擇了熱門景點中前400頁(每頁15個)的景點,結果可想而知,(ಥ﹏ಥ)為了調試因為數據增多出現的額外bug,最終的獲取的景點數據大概在4k5條左右(爬取時間為2017年09月10日,爬取關鍵詞:熱門景點,僅代表當時銷量)。

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

這樣的

還有這樣的

將地圖上熱門景點的銷量top20提取出來,大多數都是耳熟能詳的地點,故宮排在了第一位,而四川則佔據了top5中的三位,而排在top20中也四川省就佔了6位,如果不是因為地震,我想還會有更多的火爆的景點進入排行榜的~這樣看來如果你這次國慶打算去四川的話,可以腦補到的場景就是:人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人……

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

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

既然去哪些地方人多,去哪裡景多都已經知道了,那再看看去哪些地方燒得錢最多吧?下圖是由各城市景點銷售起步價的最大值-最小值扇形組成的圓,其中湖北以單景點銷售起步價600佔據首位,但也可以看到,湖北的景點銷售均價並不高(在紅色扇形中的藏藍色線條)。而如果國慶去香港玩,請做好錢包減肥的心理和生理準備(•̀ω•́)✧。

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

PS:寫了個網頁,展示百度地圖的熱力圖效果和echarts的景點排行榜,方便大家查看。http://easyinfo.online 源碼已經上傳到gayhub啦https://github.com/otakurice/notravellist/tree/master

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

Python愛好者社區歷史文章大合集

Python愛好者社區歷史文章列表(每周append更新一次)

福利:文末掃碼立刻關注公眾號,「Python愛好者社區」,開始學習Python課程:

關注後在公眾號內回復課程即可獲取:

1.崔老師爬蟲實戰案例免費學習視頻。

2.丘老師數據科學入門指導免費學習視頻。

3.陳老師數據分析報告製作免費學習視頻。

4.玩轉大數據分析!Spark2.X+Python 精華實戰課程免費學習視頻。

5.丘老師Python網絡爬蟲實戰免費學習視頻。

相關焦點

  • 我用Python爬取了全國4500個熱門景點,告訴你國慶哪兒最堵?
    那麼問題來了,去哪兒玩呢?百度輸了個「國慶」,出來的第一條居然是「去哪裡旅遊人少」……emmmmmmm,因缺思廳。因為前幾次爬蟲都是爬一些文本信息,做一下詞雲之類的,我覺得:沒!意!思!了!這次正好爬的是數據,我決定用數據的好基友——圖表來輸出我爬取的數據,也就是說我要用爬取的景點銷量以及景點的具體位置來生成一些可視化數據。
  • 我用 Python 爬取了全國 4500 個熱門景點,告訴你國慶哪裡去不得?
    那麼問題來了,去哪兒玩呢?百度輸了個「國慶」,出來的第一條居然是「去哪裡旅遊人少」……emmmmmmm,因缺思廳。因為前幾次爬蟲都是爬一些文本信息,做一下詞雲之類的,我覺得:沒!意!思!了!這次正好爬的是數據,我決定用數據的好基友——圖表來輸出我爬取的數據,也就是說我要用爬取的景點銷量以及景點的具體位置來生成一些可視化數據。
  • 我用Python爬取了全國4500個熱門景點,告訴你國慶哪兒最堵
    那麼問題來了,去哪兒玩呢?百度輸了個「國慶」,出來的第一條居然是「去哪裡旅遊人少」……emmmmmmm,因缺思廳。這次正好爬的是數據,我決定用數據的好基友——圖表來輸出我爬取的數據,也就是說我要用爬取的景點銷量以及景點的具體位置來生成一些可視化數據。安利一下百度的地圖 API 和 echarts,前者是專門提供地圖 API 的工具,聽說好多 APP 都在用它,後者是數據處理居家旅行的好夥伴,用了之後,它好,我也好(隱約覺得哪裡不對)。
  • 她用Python爬取了去哪兒網,終於不知道去哪兒了
    那麼問題來了,去哪兒玩呢?百度輸了個「國慶」,出來的第一條居然是「去哪裡旅遊人少」……emmmmmmm,因缺思廳。因為前幾次爬蟲都是爬一些文本信息,做一下詞雲之類的,中二的我覺得:沒!意!思!了!這次正好爬的是數據,我決定用數據的好基友——圖表來輸出我爬取的數據,也就是說我要用爬取的景點銷量以及景點的具體位置來生成一些可視化數據。
  • 國慶去哪玩?用Python爬取了全國4500個熱門景點,才發現...
    那麼問題來了,去哪兒玩呢?百度輸了個「國慶」,出來的第一條居然是「去哪裡旅遊人少」……emmmmmmm,因缺思廳。因為前幾次爬蟲都是爬一些文本信息,做一下詞雲之類,我覺得:沒!意!思!了!這次正好爬的是數據,我決定用數據的好基友——圖表來輸出我爬取的數據,也就是說我要用爬取的景點銷量以及景點具體位置來生成可視化數據。
  • 西海數據丨推薦 她用Python爬取了去哪兒網,終於不知道去哪兒了
    ★          ★          ★          ★          ★因為前幾次爬蟲都是爬一些文本信息,做一下詞雲之類的,中二的我覺得:沒!意!思!了!這次正好爬的是數據,我決定用數據的好基友——圖表來輸出我爬取的數據,也就是說我要用爬取的景點銷量以及景點的具體位置來生成一些可視化數據。
  • 國慶哪玩?用Python爬取了全國5000家旅遊景區(收藏)
    下面我用 Python 爬取了全國近 5000 個旅遊景點,並結合 pyecharts 來做分析技能包爬蟲Mysqlsqlalchemypyecharts>數據爬取旅遊景點的數據是從網上爬取的,該數據包含以下維度:景點名稱,所屬省市區,景點簡介,門票價格,評分,近期銷量,景點評級等。
  • python爬蟲系列教程,用python爬取全國範圍內的KFC店地址
    下面羽憶教程教你會python爬取全國範圍內的KFC店地址,這是一篇python爬蟲系列的教程,簡單又能讓人填飽肚子。python爬蟲介紹python發展至今,python爬蟲已經成為了一種職業,因為其可以幫助企業快速得到網絡上的最新信息,但是為什麼很多寫python爬蟲的程式設計師會面臨牢獄之災呢?
  • 國慶長假遊玩人次達6.37億人次,這麼多人都到哪兒去玩了呢?
    恰逢國慶中秋兩個節日重合,在家憋這麼久的人們怎麼能不出去看看祖國的大好河山。據新華網消息,整個國慶長假外出遊玩人次達 6.37 億人次,那麼這麼多人都到哪兒去玩了呢,今天我們就用 Python 做一個全國熱門景區熱點圖。
  • python爬蟲入門實戰!爬取博客文章標題和連結!
    最近有小夥伴和我留言想學python爬蟲,那麼就搞起來吧。準備階段爬蟲有什麼用呢?舉個最簡單的小例子,你需要《戰狼2》的所有豆瓣影評。最先想的做法可能是打開瀏覽器,進入該網站,找到評論,一個一個複製到文本中,保存,翻頁,接著複製,直到翻到最後一頁。
  • python為什麼叫爬蟲?為啥那麼多人通過python兼職都能掙不少錢?
    Python能做什麼之前有很多文章介紹python能做什麼。今天介紹python爬蟲的學習。網絡爬蟲 網絡爬蟲,也叫網絡蜘蛛(Web Spider)。爬蟲是根據網頁地址(URL)爬取網頁上的內容,這裡說的網頁地址(URL)就是我們在瀏覽器中輸入的網站連結。例如:https://www.baidu.com/,這就是一個URL。
  • Python爬蟲學到什麼程度就可以去找工作了?
    有朋友在群裡和大家討論,問的最多的問題就是,python 爬蟲學到什麼程度可以去找工作了,關於這點,和大家分享下我的理解。去招聘網上看看需求都有哪些,直接做個拉勾網爬蟲(有需要的私信)出結果了:仔細看看,我們可以得出以下幾點:1、 python 不是唯一可以做爬蟲的,很多語言都可以,
  • Python網絡爬蟲
    Python網絡爬蟲第一篇(一):為什麼要學習網絡爬蟲?大數據成為當今時代的熱門話題之一,在數據量爆發增長的網際網路時代,網站與用戶溝通實質為數據的交換。如果大量的數據得以分析,我們能夠對事件的看法,解決方案做出更好的決策。
  • 如何開始寫你的第一個python腳本——簡單爬蟲入門!
    好多朋友在入門python的時候都是以爬蟲入手,而網絡爬蟲是近幾年比較流行的概念,特別是在大數據分析熱門起來以後,學習網絡爬蟲的人越來越多,哦對,現在叫數據挖掘了!其實,一般的爬蟲具有2個功能:取數據和存數據!好像說了句廢話。。。
  • Python開發簡單爬蟲【學習資料總結】
    ;另一方面,會將新的URL補充進URL管理器,若有URL管理器中含有新的URL,則重複上述步驟,直到爬取完所有的URL 6、最後,調度器會調動應用的方法,將價值數據輸出到需要的格式。
  • 雲立方網科普:常用高效的Python爬蟲框架有哪些?
    Python是現在非常流行的程式語言,而爬蟲則是Python語言中最典型的應用,下面是總結的高效Python爬蟲框架,大家看看是否都用過呢。
  • 聊聊學python轉行、具體學習方法、自學python用於辦公、寫爬蟲等...
    反覆練習的時候,速度是一定會提升的,比如說一個案例做第1遍的時候用了4個小時,第2遍可能只需用2個小時,第3遍的時候很熟練了可能僅僅只需要1個小時,熟練度越來越高代表著記憶越來越牢。熟練了之後就不需要再重複了。一次成功的提取抵得上十次心不在焉的閱讀。
  • 用python分析上海二手房數據,用幾十行代碼爬取大規模數據!
    spider_1('http://esf.xian.fang.com/')4、循環翻頁爬取二手房信息考慮到每頁只顯示30條,總共100頁,寫一個循環調用的語句,把100頁的內容全部爬下來# 循環,把第2-100頁全部爬下來page = 1while
  • 重慶科技學院首屆「曙光瑞翼杯」Python爬蟲競賽
    但是在大數據浪潮中,最值錢的就是數據,企業為了獲得數據,處理數據,理解數據花費了巨大代價,網絡爬蟲則是獲取簡單數據的一種最有效的方式。近日,數據中國「百校工程」項目院校重慶科技學院數理與大數據學院MAI協會聯合曙光瑞翼教育舉辦了首屆以「Python爬蟲,數據輕來」為主題的「曙光瑞翼杯」Python爬蟲大賽,全校一共16支隊伍參賽。
  • python爬蟲之selenium抓取淘寶商品信息
    簡介本節採用python爬蟲相關技術獲取淘寶商品信息。採用的技術有selenium、pyquery及urllib.parse等。selenium可以模擬用戶執行的操作,是一個自動化測試工具,我們可以根據自己的需要預先設置selenium按照我們設置好的步驟進行操作,而在爬蟲中我們使用selenium可以解決javascript動態執行代碼的問題,不用費心去解析js如何運行,運行後產生的信息,直接使用selenium模擬實際登陸網頁的操作,獲取我們需要的信息進行分析,成功幫我們避開一系列複雜的通信過程,方便使用者。