爬取美團

實戰 Python 網絡爬蟲:美團美食商家信息和用戶評論

1、網站分析及項目設計

美食是人類的畢生追求,說到美食,咱們總會想起美團美食,面對類型衆多的商家,應如何選擇優質的商家,使消費最大合理化。在本 Chat 裏,將講述如何爬取美團商家信息。正則表達式

廢話很少說,咱們直接在瀏覽器打開美團美食的網址,而後打開谷歌的開發者工具,並刷新網頁,從新捕捉請求資源,如圖所示:sql

根據店名在 Network 選項卡的各個分類標籤下查找數據所在的 HTML 源碼位置,在每一個請求信息的 Response 下使用 Ctrl+F 快速查找店名(初漾臺味黑糖),最終在 Doc 標籤下找到相關信息,如圖所示:數據庫

從圖上的信息能夠看到,地址欄的 gz 表明區域「廣州」,全國的美食商家是以城市進行劃分的。而商家的數據是以 JSON 格式表示,網頁上顯示的信息均可以在此找到。在這個網頁中,咱們是要查找這個商家的 URL 地址,從而進入商家詳細頁。瀏覽器

但從美團美食的首頁中,咱們能獲取的信息就這麼多,所以,咱們先訪問店家詳細頁,發現商家詳細頁的 URL 地址帶有一串數字。不一樣的商家,數字內容都不同,如圖所示:markdown

經過對比發現,每一個商家詳細頁的 URL 地址只有末端的數字串是不相同的,這應該是美團給商家標記的 id,咱們取其中一個商家 id 回到美團首頁查找,發現可找到相關信息,如圖所示:網絡

根據上述分析,咱們能夠在美團美食首頁裏獲取商家 id,經過 id 來構建商家詳細頁的 URL 地址。框架

獲得了商家詳細頁的 URL 地址後,下一步是在商家詳細頁裏進行數據爬取。數據爬取分爲兩部分:商家信息和顧客評論,如圖所示:函數

首先,咱們找出商家信息所在的請求信息,在開發者工具的 Network 選項卡的 doc 標籤下找到相關信息,商家信息是在 doc 標籤下找到,而且也是以 JSON 格式表示,如圖所示:工具

接着是分析顧客評論所在的請求信息,最終在 XHR 標籤下找到相關的請求信息,如圖所示:網站

綜合上述,咱們須要從三個請求信息裏獲取數據,三個請求信息的說明以下:

  • 美團美食的首頁地址,獲取每一個商家的 id
  • 商家詳細頁地址,獲取商家信息
  • 顧客評論的 AJAX 接口,獲取顧客評論信息

目前只是簡單分析了三個請求信息,每一個請求的請求參數和請求頭會在功能實現的過程當中詳細講解。

根據現有的分析,咱們建立項目文件夾 meituan,項目文件分別有 Insql.py、meishi.conf 和 meishi.py,文件說明以下:

  • Insql.py 是將數據入庫處理,由 ORM 框架 SQLAlchemy 實現
  • meishi.conf 設置區域信息,如廣州(gz)或北京(bj)等,從而控制爬蟲的爬取方向
  • meishi.py 實現爬蟲功能

 

2、爬取全部商家信息

簡單分析網頁後,接下來咱們先實現全部商家的信息爬取。因爲商家詳細頁只須要商家 id 便可,所以爬取全部商家信息只需爬取商家 id 便可。

從美團美食的首頁得知,其 URL 地址的「gz」表明廣州。首頁的底部設有分頁功能,當點擊第二頁的時候,URL 末端新增下級目錄 pn2,第三頁的下級目錄爲 pn3,以此類推,新增的下級目錄表明分頁的頁數。當遍歷 32 次便可獲得當前城市全部美食商家信息,如圖所示:

根據 URL 的變化規律和商家信息的 HTML 源碼結構,全部商家信息的爬取功能定義爲函數 get_all(),函數參數 city_list 表明各個城市信息並以字符串表示,如 gz、bj 等,函數代碼如圖所示:

函數 get_all() 所實現的功能說明以下:

  • 首先將參數 city_list 以英文逗號進行截取,獲得各個城市的拼音縮寫。
  • 而後遍歷各個城市,分別爬取各個城市的美食信息,每一個城市只顯示 32 頁的美食信息,所以須要遍歷 32 次。
  • 每次遍歷都會對當前分頁發送 HTTP 請求,請求頭設有 Upgrade-Insecure-Requests、Host 和 Referer 屬性,這些屬性最好寫入請求頭,這樣能夠避開反爬蟲檢測。特別是 Host 屬性,由於 URL 的域名設有城市信息,如 gz.meituan.com,而 Host 屬性是爲 URL 指定相應的域名,使其一一對應。
  • 從當前請求中獲取響應內容,並用正則表達式提取當前分頁全部的商家 id(即find_poiId)以及訪客信息 find_uuid。
  • 調用函數 get_info(),將爬取的數據做爲函數參數傳入。函數 get_info() 是進入商家詳細頁,爬取商家的基本信息。

 

3、分別爬取每一個商家的信息和用戶評論信息

在函數 get_all() 裏,咱們調用了函數 get_info(),它是進入訪問商家詳細頁的,主要爬取商家的基本信息。商家詳情頁的 URL 地址爲 http://www.meituan.com/meishi/%s/,其中 %s 表明商家 id。

注意:若是對商家詳細頁發送 HTTP 請求,這裏涉及了一個反爬蟲機制——Cookies 的使用,咱們查看該請求的請求頭內容。如圖所示:

商家詳細頁的請求頭與通常的請求頭並沒有太大差別,按照以往的開發模式,首先構架 URL 地址,而後對 URL 發送請求,最後從請求裏獲取響應內容並提取目標數據。按照該思路,商家的基本信息爬取功能如圖所示:

當運行程序的時候,程序是沒有提取到商家信息了,這說明該請求的響應內容不是商家詳細頁的網頁內容,確定遇到反爬蟲檢測。在請求頭裏,除了還沒有加入 Cookies 以外,其他屬性已添加,所以,咱們嘗試加入 Cookies,發現能夠提取到商家信息。

可是隻使用一個 Cookies 也會中斷爬取過程,緣由在於訪問頻繁。爲了下降訪問頻繁,引入 Cookies 池,將代碼的請求部分進行修改,以下所示:

從函數 get_info() 裏可到,它調用了函數 get_comment(),並將商家 ID 和 find_uuid 分別傳入,find_uuid 是從函數 get_all()提取出來的數據,這兩個函數參數都是構建顧客評論的 AJAX 接口的請求參數,如圖所示:

  • 請求參數 uuid 是函數參數 find_uuid
  • 請求參數 originUrl 是商家詳細頁的 URL 地址
  • 請求參數 id 是商家 id

所以,函數 get_comment() 的代碼如圖所示:

 

4、ORM 框架實現數據持久化存儲

爬蟲的核心功能大體已實現,接着講解數據存儲方面。數據存儲以 MySQL 爲例,存儲過程使用 ORM 框架 SQLAlchemy,這樣可實現數據持久化,它的優勢此處不一一講述。

首先在 Insql.py 裏導入 ORM 框架 SQLAlchemy,並建立相關對象,經過 SQLAlchemy 鏈接本地 MySQL 數據庫。數據庫編碼設爲 UTF8mb4,由於評論信息裏可能出現手機表情這類特殊內容,這些特殊內容是超出 UTF-8 的編碼範圍。代碼以下:

將商家信息和顧客評論信息分別存儲在數據表 meituan_shop 和 meituan_comment。數據表之間存在一對多的數據關係,一個商家會有多條顧客評論,映射類的定義以下:

上述只是定義映射類,數據存儲的功能還沒有實現。數據存儲由函數 shop_db() 和函數 comment_db() 實現,二者會對待存儲的數據進行判斷,若是數據已存在數據庫,則進行更新處理,反之新增一條數據。代碼以下:

 

5、設置配置文件,動態控制爬取方向

配置文件給爬蟲程序 meishi.py 讀取,用於控制爬蟲的爬取方向,好比爬取北京、上海等城市的美食信息。將配置文件命名爲 meishi.conf,配置信息以下:

配置文件只設置配置屬性 city,屬性值是將每一個城市編號以英文逗號的形式拼接起來,城市編號是首個字母拼音開頭組成的。函數 get_all() 的函數參數 city_list 就是配置屬性 city。

在爬蟲文件 meishi.py 裏,文件運行函數 _main_ 主要讀取配置文件的配置屬性 city,並調用函數 get_all(),代碼以下:

 
 
 
 
 
 
本內容轉自:帥b大佬的博客
相關文章
相關標籤/搜索