爬取美團網的美食點評信息(含頁面分析過程)

寫在前面:

       憑藉興趣寫了很多爬蟲的小程序,但是都沒有以博文的形式分享出來。爬取美團網的數據是因爲課題研究需要,已經將深圳所有的美團店鋪評論數據爬取完畢(大衆點評和百檽米的相應區域也已爬取完畢,對爬蟲有興趣可以看我的GitHub主頁:https://github.com/slpslpslp ,覺得不錯的幫忙加個星,謝謝)。這是寫的第一篇爬蟲博客,這裏只簡單分析思路,代碼我的主頁上有。

分析過程:

        我爬取的區域是深圳市,因此以深圳的美食爲例,分析其網頁架構: 

        我的最終目的是要獲取深圳市美團上美食裏面的每一個店鋪裏面的每條評論信息。因此我應該從整個深圳市美食裏入手。

      (1)將整個深圳市切化到行政區子塊

     這是通過選擇美食深圳兩個標籤之後的頁面。這樣我們有三種策略進行分塊爬取操作:1:按照菜品分類;2:按照區域;3:按照用餐人數。在這裏你會發現:當你選擇菜品分類時,如果你點擊“代金券”,那麼其網頁路由相應由http://sz.meituan.com/meishi/變爲"http://sz.meituan.com/meishi/c393/",那麼變化就在於後者多了‘c393’,因此c393就是”代金券“的類別號。同理,以區域選擇時,我們也可以獲得其區域類別號。由於區域方便理解與管理,因此我採取的是分行政區爬取店鋪信息。

  (2)將整個深圳市切化到行政區子塊

     同時,在一個區內又有很多子區域,因此我們需要知道子區域的分類號,當點擊”香蜜湖“的時候,發現網頁是http://sz.meituan.com/meishi/b1056/,因此b1056代表的就是香蜜湖美食分類號。進入到香蜜湖美食頁面中,我們發現區域已經不能再細分了,那麼ok,可以開始思考如何獲取其店鋪信息了。

  (3)通過瀏覽器開發者功能解析網頁中數據來源

        在這裏推薦使用FireFox的Web開發者和Chrome的開發者工具,這裏以Chrome瀏覽器爲例。按下F12,點到NetWork選項下。這裏有個小技巧:我們先刷新一下頁面試試,看看頁面中哪些區域是XHR的返回結果(就是點擊刷新有變化的區域,也就是所謂的異步加載)。一:如果頁面整體刷新,那麼我們可以直接解析返回的html,也就是瀏覽器中ALL下Type裏面document內容,通過BeautifulSoup、re正則解析和xpath解析即可。二:如果頁面部分刷新,在本例中,店鋪展示區域異步刷新了,那麼我們就直接通過點擊Network下的XHR過濾掉其他不必要的信息。

點擊xhr裏面的信息,我們發現,這個裏面就是保存了我們想要的信息,包括店鋪id(進入店鋪詳細頁的入口)、店鋪的各項其他概述信息以及十分重要的子區域店鋪總數量‘totalCounts’信息(通過它我們可以知道有多少頁店鋪信息)。

在我們獲取了店鋪id後,就已經獲得了店鋪詳細信息的入口。例如上上個頁面中的“順德大盤魚”店鋪,它的店鋪詳細url是:http://www.meituan.com/meishi/6214364/ 。

在店鋪詳細頁面裏面,我截的第一張圖裏需要在html裏面解析出其人均、評分、地址、經緯度信息(這個也在html裏面,)、電話等信息。具體解析在在getEachPoiShopsInfos.py裏面有:

def parseShopHtml(html):
    html = str(html)
    pattern = re.compile('"detailInfo":(.*?),"photos"', re.S)
    # 注意,有些店鋪已經消失了,所以需要判斷是否是回到了美團主界面
    if re.search(pattern, html):
        detailInfos = re.search(pattern, html).group(1)
    else:
        return False
    # 將解析到的字符串轉爲字典
    detailInfo_dict = json.loads(detailInfos)
    shopId = detailInfo_dict.get('poiId')
    shopName = detailInfo_dict.get('name')
    longitude = detailInfo_dict.get('longitude')
    avgScore = detailInfo_dict.get('avgScore')
    latitude = detailInfo_dict.get('latitude')
    openTime = detailInfo_dict.get('openTime')
    address = detailInfo_dict.get('address')
    phone = detailInfo_dict.get('phone')
    avgPrice = detailInfo_dict.get('avgPrice')
    shopInfos = pd.DataFrame(
        {'shopId': [shopId], 'shopName': [shopName], 'longitude': [longitude], 'avgScore': [avgScore],
         'latitude': [latitude], 'openTime': [openTime], 'address': [address], 'phone': [phone],
         'avgPrice': [avgPrice]})
    shopInfos.to_csv('./{0}S.csv'.format(shopId), index=False)
    return True

店鋪詳細頁的評論信息,和前面店鋪的id獲取一樣,也是XHR異步加載得來的(知道數據來源就很簡單了,就只是解析json字符串而已)

(4)最終獲取的數據展示

寫到最後

        這份代碼我是幾個月前寫的了,當時並沒有考慮使用Scrapy(高效率爬取框架),也沒有使用多線程多進程,是一個行政區的一個小區域這樣子慢慢獲取的,所以效率不太高。另外,當時有段時間我的ip被禁了,我就用了代理ip池去獲取的,但是通過西刺代理這類的代理ip其實很劣質,要有效的還是得掏錢。不過後來我發現怎麼爬都不禁我的ip了,甚是奇怪。最後,畢竟過了這麼久,可能一些細節的頁面規則有所改動,但是改動應該不大,所以如果想直接用我的代碼獲取數據,可能需要自己稍微改改。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章