Python 爬取大眾點評 50 頁數據,最好吃的成都火鍋竟是它!


前言

文的文字及圖片來源於網絡,僅供學習、交流使用,不具有任何商業用途,版權歸原作者所有,如有問題請及時聯系我們以作處理。

作者: 胡蘿卜醬

PS:如有需要Python學習資料的小伙伴可以加點擊下方鏈接自行獲取

http://note.youdao.com/noteshare?id=3054cce4add8a909e784ad934f956cef

爬蟲

首先筆者定位為成都,美食類型選的“火鍋”,火鍋具體類型選的不限,區域選的不限,排序選的智能,如圖: 在這里插入圖片描述

你也可以選擇別的選項,只是注意URL的變化。本文都是按照上述選項爬取的數據。接下來翻頁觀察一下URL的變化:

第二頁:

在這里插入圖片描述

第三頁:

在這里插入圖片描述

很容易觀察出翻頁變化的知識p后面的數字,倒推回第一頁,發現一樣的顯示內容,因此,寫一個循環,便可以爬取全部頁面。

但是大眾點評只提供了前50頁的數據,所以,我們也只能爬取前50頁。

這一次,筆者用的pyquery來分析網頁的,所以我們需要定位到我們所爬取的數據的位置,如圖: 在這里插入圖片描述

在具體分析的網頁的時候,我震驚了,大眾點評的反爬做的太過分了,它的數字,一些文字居然都不是明文顯示,而是代碼,你還不知道怎么分析它。如圖:

在這里插入圖片描述

很煩的,一些文字又可以顯示,一些又用代碼表示。一些數字也是,不過好一點的是數字只有9個,只要稍微觀察一下,就能發現數字的代碼是什么了。這里筆者列出來了。 {'hs-OEEp': 0, 'hs-4Enz': 2, 'hs-GOYR': 3, 'hs-61V1': 4, 'hs-SzzZ': 5, 'hs-VYVW': 6, 'hs-tQlR': 7, 'hs-LNui': 8, 'hs-42CK': 9}。值得注意的是,數字1,是用明文表示的。

那么,如何用pyquery來定位呢,很簡單,你找到你要獲取的數據,然后右鍵→copy→cut selector,你復制到代碼里面就OK了。pyquery的具體用法百度既有。

在這里插入圖片描述

最后,我們獲取了火鍋50個頁面的數據,每頁15個數據,一共750家餐廳的數據。

在這里插入圖片描述

分析

大眾點評已經給出了星級評價,可以看看大致趨勢。

在這里插入圖片描述

准五星商戶最多,可能因為大部分食客都習慣給好評,只有實在不滿時才會打出低評有關,造成了評級一般不低,但近滿分還是蠻少的。

在本文,我們假設評論數目為飯店的熱度,也就是它越火,評論數目越多。

在這里插入圖片描述

評論數目大多在1000以內,但是高於2000,甚至高於4000也還存在一些,這些飯店應該是一些網紅店。以5000為約束,篩選出飯店均為小龍坎、蜀大俠都非常知名的火鍋店。那么評論數量和星級有關系嗎?看下圖: 在這里插入圖片描述

這里取其評論數平均值,發現對於四星以上商戶來說,評論數和星級並不關系,但均比低於四星的飯店銷量更好。這說明在四星以上之后,人們選擇差別不大,但一般不願意接受評論太差的飯店。

對於筆者這樣的學生黨來說,影響較大還有人均消費情況。

在這里插入圖片描述

成都的火鍋店人均消費大部分都在50-100的區間內,高於150的也有一些。對於筆者來講,吃一頓火鍋,人均在50-100是可以接受的,高於100,就要低頭看看錢包了()。那擴展看,人均消費和星級、評論數量有關系嗎? 在這里插入圖片描述

上圖是人均消費和星級的關系,看起來並無任何關系,那說明一些口碑好的火鍋店,其實人均也不貴。下面看看人均和評論數目的關系吧。

在這里插入圖片描述

通過比較,發現評論數目低於500,人均在50-100區間是最多的。當然這肯定和評論數量、人均消費本身集中於這一階段有關。

吃火鍋,一家店的生意好壞,肯定還和它的特色菜有關,筆者通過jieba分詞,將爬取到的推薦菜做了一個詞雲圖,如下。 在這里插入圖片描述

筆者最愛的牛肉是特色菜之最啊,尤其是麻辣牛肉,只要去吃火鍋,都要來上一份,其次是毛肚、蝦滑、鵝腸等等。

接下來是大家都關心的,口味、環境和服務的情況。

在這里插入圖片描述

三者得分大多都是集中在8.0-9.2這一階段,筆者認為,低於7.5分的飯店還是不要去嘗試了。同時,星級評價應該也是由這三者得分產生的。

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

果然如預想的一向,星級評價越好,它在口味、環境和服務的得分越高。那么口味,環境,服務得分與評論數量,平均價格有關系嗎?

在這里插入圖片描述

如圖所看,並無什么直接關系,但是我們發現口味、環境和服務三者之間存在着非常好的線性關系,於是單獨拿出來畫了一個較大的圖。

在這里插入圖片描述

我們並且擬合了線性關系,由於三星商戶只有一家,它的情況較為特殊之外,其他星級在口味、環境和服務的關系擬合中保持的相當一致,這也證明我們的猜想,這些變量之間存在線性關系。鑒於筆者本文最大的目的是做推薦,於是,我們進行了K-means聚類,這里取K為3,並且把星級轉換為數字,五星對應5分,准五星對應4.5分,以此類推。最終得到了三類,通過作圖,看看聚類情況如何吧。

在這里插入圖片描述

和我們想要的結果一致,在口味、環境、服務和星級上得分越高,我們就越推薦。然而推薦的店鋪還是好多,能不能在集中一些呢?於是通過限制評論數量、人均消費和特色菜來進行推薦。由於筆者喜歡人少,便宜還有牛肉的店鋪,這里得到了如下的結果:

在這里插入圖片描述

代碼

 1 import time
 2 import requests
 3 from pyquery import PyQuery as pq
 4 import pandas as pd
 5  6 headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'}
 7  8 def restaurant(url):
 9     # 獲取網頁靜態源代碼
10     try:
11         response = requests.get(url, headers=headers)
12         if response.status_code == 200:
13             return response.text
14     except Exception:
15         return None
16 17 name=[]
18 url = [] 
19 star = []
20 comment = []
21 avg_price = []
22 taste = []
23 environment = []
24 services = []
25 recommend = []
26 27 num = {'hs-OEEp': 0, 'hs-4Enz': 2, 'hs-GOYR': 3, 'hs-61V1': 4, 'hs-SzzZ': 5, 'hs-VYVW': 6, 'hs-tQlR': 7, 'hs-LNui': 8, 'hs-42CK': 9}
28 def detail_number(htm):
29     try:
30         a = str(htm)
31         a = a.replace('1<', '<span class="1"/><')
32         a = a.replace('.', '<span class="."/>')
33         b = pq(a)
34         cn = b('span').items()
35         number = ''
36         for i in cn:
37             attr = i.attr('class')
38             if attr in num:
39                 attr = num[attr]
40             number = number + str(attr)
41         number = number.replace('None', '')
42     except:
43         number = ''
44     return number
45 46 def info_restaurant(html):
47     # 獲取飯店的名稱和鏈接
48     doc = pq(html)
49     for i in range(1,16):
50         #獲取飯店名稱
51         shop_name = doc('#shop-all-list > ul > li:nth-child('+str(i)+') > div.txt > div.tit > a:nth-child(1) > h4').text()
52         if shop_name == '':
53             break
54         name.append(shop_name)
55         #獲取飯店鏈接
56         url.append(doc('#shop-all-list > ul > li:nth-child('+str(i)+') > div.pic > a').attr('href'))
57         try:
58             star.append(doc('#shop-all-list > ul > li:nth-child('+str(i)+') > div.txt > div.comment > span').attr('title'))
59         except:
60             star.append("")
61         #獲取評論數量
62         comment_html = doc('#shop-all-list > ul > li:nth-child('+str(i)+') > div.txt > div.comment > a.review-num > b')
63         comment.append(detail_number(comment_html))
64         #獲取人均消費
65         avg_price_html = doc('#shop-all-list > ul > li:nth-child('+str(i)+') > div.txt > div.comment > a.mean-price > b')
66         avg_price.append(detail_number(avg_price_html))
67         #獲取口味評分
68         taste_html = doc('#shop-all-list > ul > li:nth-child('+str(i)+') > div.txt > span > span:nth-child(1) > b')
69         taste.append(detail_number(taste_html))
70         #獲取環境評分
71         environment_html = doc('#shop-all-list > ul > li:nth-child('+str(i)+') > div.txt > span > span:nth-child(2) > b')
72         environment.append(detail_number(environment_html))
73         #獲取服務評分
74         services_html = doc('#shop-all-list > ul > li:nth-child('+str(i)+') > div.txt > span > span:nth-child(3) > b')
75         services.append(detail_number(services_html))
76         #推薦菜,都是顯示三道菜
77         try:
78             recommend.append(doc('#shop-all-list > ul > li:nth-child('+str(i)+') > div.txt > div.recommend > a:nth-child(2)').text()+str(',')+\
79                             doc('#shop-all-list > ul > li:nth-child('+str(i)+') > div.txt > div.recommend > a:nth-child(3)').text()+str(',')+\
80                             doc('#shop-all-list > ul > li:nth-child('+str(i)+') > div.txt > div.recommend > a:nth-child(4)').text())
81         except:
82             recommend.append("")
83 for i in range(1,51):
84     print('正在獲取第{}頁飯店信息'.format(i))
85     hotpot_url = 'http://www.dianping.com/chengdu/ch10/g110p'+str(i)+'?aid=93195650%2C68215270%2C22353218%2C98432390%2C107724883&cpt=93195650%2C68215270%2C22353218%2C98432390%2C107724883&tc=3'
86     html = restaurant(hotpot_url)
87     info_restaurant(html)
88     print ('第{}頁獲取成功'.format(i))
89     time.sleep(12)
90 91 shop = {'name': name, 'url': url, 'star': star, 'comment': comment, 'avg_price': avg_price, 'taste': taste, 'environment': environment, 'services': services, 'recommend': recommend}
92 shop = pd.DataFrame(shop, columns=['name', 'url', 'star', 'comment', 'avg_price','taste', 'environment', 'services', 'recommend'])
93 shop.to_csv("shop.csv",encoding="utf_8_sig",index = False)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM