自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

100行代碼爬取全國所有必勝客餐廳信息

開發(fā) 后端 數(shù)據(jù)分析
數(shù)據(jù)分析的前提是有數(shù)據(jù)可分析。如果沒有數(shù)據(jù)怎么辦?一是可以去一些數(shù)據(jù)網(wǎng)站下載相關(guān)的數(shù)據(jù),不過數(shù)據(jù)內(nèi)容可能不是自己想要的。二是自己爬取一些網(wǎng)站數(shù)據(jù)。今天,我就爬取全國各地所有的必勝客餐廳信息,以便后續(xù)做數(shù)據(jù)分析。

當(dāng)我剛接觸 Python 時,我已經(jīng)被 Python 深深所吸引。Python 吸引我的地方不僅僅能用其編寫網(wǎng)絡(luò)爬蟲,而且能用于數(shù)據(jù)分析。我能將大量的數(shù)據(jù)中以圖形化方式呈現(xiàn)出來,更加直觀的解讀數(shù)據(jù)。

數(shù)據(jù)分析的前提是有數(shù)據(jù)可分析。如果沒有數(shù)據(jù)怎么辦?一是可以去一些數(shù)據(jù)網(wǎng)站下載相關(guān)的數(shù)據(jù),不過數(shù)據(jù)內(nèi)容可能不是自己想要的。二是自己爬取一些網(wǎng)站數(shù)據(jù)。

今天,我就爬取全國各地所有的必勝客餐廳信息,以便后續(xù)做數(shù)據(jù)分析。

01抓取目標

我們要爬取的目標是必勝客中國。打開必勝客中國首頁,進入“餐廳查詢”頁面。

100行代碼爬取全國所有必勝客餐廳信息

我們要爬取的數(shù)據(jù)內(nèi)容有城市、餐廳名字、餐廳地址以及餐廳聯(lián)系電話。因為我看到頁面中有地圖,所以頁面一定有餐廳地址的經(jīng)緯度。因此,餐廳的經(jīng)緯度也是我們需要爬取的數(shù)據(jù)。

至于全國有必勝客餐廳的城市列表,我們可以通過頁面的“切換城市”獲取。

100行代碼爬取全國所有必勝客餐廳信息

02分析目頁面

在編寫爬蟲程序之前,我都是先對頁面進行簡單分析,然后指定爬取思路。而且對頁面結(jié)構(gòu)進行分析往往會有一些意想不到的收獲。

我們使用瀏覽器的開發(fā)者工具對頁面結(jié)構(gòu)進行簡單分析。

100行代碼爬取全國所有必勝客餐廳信息

我們在 StoreList 頁面中能找到我們所需的數(shù)據(jù)。這個能確定數(shù)據(jù)提取的 Xpath 語法。

StoreList 頁面的 Response 內(nèi)容比較長。我們先不著急關(guān)閉頁面,往下看看,找找看是否有其他可利用的內(nèi)容。***,我們找到調(diào)用獲取餐廳列表信息的 JavaScript 函數(shù)代碼。

100行代碼爬取全國所有必勝客餐廳信息

我們接著搜索下GetStoreList函數(shù),看看瀏覽器如何獲取餐廳列表信息的。

100行代碼爬取全國所有必勝客餐廳信息

從代碼中,我們可以了解到頁面使用 Ajax 方式來獲取數(shù)據(jù)。頁面以 POST 方式請求地址http://www.pizzahut.com.cn/StoreList/Index。同時,請求還攜帶參數(shù) pageIndex 和 pageSize。

03爬取思路

經(jīng)過一番頁面結(jié)構(gòu)分析之后,我們指定爬取思路。首先,我們先獲取城市信息。然后將其作為參數(shù),構(gòu)建 HTTP 請求訪問必勝客服務(wù)器來獲取當(dāng)前城市中所有餐廳數(shù)據(jù)。

為了方便數(shù)據(jù)爬取,我將所有城市全部寫入到 cities.txt 中。等要爬取數(shù)據(jù)時,我們再從文件中讀取城市信息。

爬取思路看起來沒有錯,但是還是有個難題沒有搞定。我們每次打開必勝客的官網(wǎng),頁面每次都會自動定位到我們所在的城市。如果無法破解城市定位問題,我們只能抓取一個城市數(shù)據(jù)。

于是乎,我們再次瀏覽首頁,看看能不能找到一些可用的信息。最終,我們發(fā)現(xiàn)頁面的 cookies 中有個 iplocation 字段。我將其進行 Url 解碼,得到 深圳|0|0 這樣的信息。

100行代碼爬取全國所有必勝客餐廳信息

看到這信息,我恍然大悟。原來必勝客網(wǎng)站根據(jù)我們的 IP 地址來設(shè)置初始城市信息。如果我們能偽造出 iplocation 字段信息,那就可以隨便修改城市了。

04代碼實現(xiàn)

***步是從文件中讀取城市信息。

 

  1. # 全國有必勝客餐廳的城市, 我將城市放到文件中, 一共 380 個城市 
  2. cities = [] 
  3.  
  4. def get_cities(): 
  5.     """ 從文件中獲取城市 """  file_name = 'cities.txt' 
  6.   with open(file_name, 'r', encoding='UTF-8-sig'as file: 
  7.         for line in file: 
  8.             city = line.replace(' 
  9. ', '') 
  10.             cities.append(city) 

第二步是依次遍歷 cities 列表,將每個城市作為參數(shù),構(gòu)造 Cookies 的 iplocation 字段。

  1. # 依次遍歷所有城市的餐廳 
  2. for city in cities: 
  3.     restaurants = get_stores(city, count
  4.     results[city] = restaurants 
  5.     count += 1 
  6.   time.sleep(2) 

然后,我們再以 POST 方式攜帶 Cookie 去請求必勝客服務(wù)器。***再對返回頁面數(shù)據(jù)進行提取。

  1. def get_stores(city, count): 
  2.     """ 根據(jù)城市獲取餐廳信息 """ 
  3.     session = requests.Session() 
  4.     # 對【城市|0|0】進行 Url 編碼 
  5.     city_urlencode = quote(city + '|0|0'
  6.     # 用來存儲首頁的 cookies 
  7.     cookies = requests.cookies.RequestsCookieJar() 
  8.  
  9.     headers = { 
  10.         'User-agent''Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 UBrowser/6.2.3964.2 Safari/537.36'
  11.         'accept''text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'
  12.         'Host''www.pizzahut.com.cn'
  13.         'Cache-Control''max-age=0'
  14.         'Connection''keep-alive'
  15.     } 
  16.  
  17.     print('============第'count'個城市:', city, '============'
  18.     resp_from_index = session.get('http://www.pizzahut.com.cn/', headers=headers) 
  19.     # print(resp_from_index.cookies) 
  20.     # 然后將原來 cookies 的 iplocation 字段,設(shè)置自己想要抓取城市。 
  21.     cookies.set('AlteonP', resp_from_index.cookies['AlteonP'], domain='www.pizzahut.com.cn'
  22.     cookies.set('iplocation', city_urlencode, domain='www.pizzahut.com.cn'
  23.     # print(cookies) 
  24.  
  25.     page = 1 
  26.     restaurants = [] 
  27.  
  28.     while True
  29.         data = { 
  30.             'pageIndex': page, 
  31.             'pageSize'"50"
  32.         } 
  33.  
  34.         response = session.post('http://www.pizzahut.com.cn/StoreList/Index', headers=headers, data=data, cookies=cookies) 
  35.         html = etree.HTML(response.text) 
  36.         # 獲取餐廳列表所在的 div 標簽 
  37.         divs = html.xpath("//div[@class='re_RNew']"
  38.         temp_items = [] 
  39.         for div in divs: 
  40.             item = {} 
  41.             content = div.xpath('./@onclick')[0] 
  42.             # ClickStore('22.538912,114.09803|城市廣場|深南中路中信城市廣場二樓|0755-25942012','GZH519'
  43.             # 過濾掉括號和后面的內(nèi)容 
  44.             content = content.split('('')[1].split(')')[0].split('','')[0] 
  45.  
  46.             if len(content.split('|')) == 4: 
  47.                 item['coordinate'] = content.split('|')[0] 
  48.                 item['restaurant_name'] = content.split('|')[1] + '餐廳' 
  49.                 item['address'] = content.split('|')[2] 
  50.                 item['phone'] = content.split('|')[3] 
  51.             else
  52.                 item['restaurant_name'] = content.split('|')[0] + '餐廳' 
  53.                 item['address'] = content.split('|')[1] 
  54.                 item['phone'] = content.split('|')[2] 
  55.             print(item) 
  56.             temp_items.append(item) 
  57.  
  58.         if not temp_items: 
  59.             break 
  60.         restaurants += temp_items 
  61.         page += 1 
  62.         time.sleep(5) 
  63.     return restaurants 

第三步是將城市以及城市所有餐廳信息等數(shù)據(jù)寫到 Json 文件中。

  1. with open('results.json''w', encoding='UTF-8'as file: 
  2.     file.write(json.dumps(results, indent=4, ensure_ascii=False)) 

05爬取結(jié)果

程序運行完之后, 就會在當(dāng)前目錄下生成一個名為「results.json」文件。完整代碼請見GitHub:

https://github.com/monkey-soft/SchweizerMesser/tree/master/Pizzahut

100行代碼爬取全國所有必勝客餐廳信息

關(guān)于作者:極客猴,熱衷于 Python,目前擅長利用 Python 制作網(wǎng)絡(luò)爬蟲以及 Django 框架。

責(zé)任編輯:未麗燕 來源: Python中文社區(qū)
相關(guān)推薦

2018-12-10 15:53:41

Python必勝客數(shù)據(jù)分析

2023-04-11 22:03:36

2017-08-01 17:02:19

代碼Python數(shù)據(jù)

2023-05-04 07:34:37

Rust代碼CPU

2021-12-16 06:21:16

React組件前端

2017-02-08 14:16:17

C代碼終端

2020-08-21 13:40:17

Python代碼人體膚色

2023-11-27 07:10:06

日志中間件

2018-01-10 22:19:44

2017-11-17 19:56:46

爬蟲視頻信息數(shù)據(jù)庫

2020-03-26 12:38:15

代碼節(jié)點數(shù)據(jù)

2015-02-09 10:43:00

JavaScript

2019-05-05 09:46:01

Python代碼神經(jīng)網(wǎng)絡(luò)

2020-12-07 10:59:01

Python數(shù)據(jù)工具

2015-09-01 16:26:18

Linux內(nèi)核

2020-07-20 09:20:48

代碼geventPython

2023-02-01 22:40:38

shellDocker

2013-09-09 10:52:10

2020-07-15 09:40:37

代碼Python瀏覽記錄

2015-10-10 14:33:55

點贊
收藏

51CTO技術(shù)棧公眾號