100行代码爬取全国所有必胜客餐厅信息

开发 后端 数据分析
数据分析的前提是有数据可分析。如果没有数据怎么办?一是可以去一些数据网站下载相关的数据,不过数据内容可能不是自己想要的。二是自己爬取一些网站数据。今天,我就爬取全国各地所有的必胜客餐厅信息,以便后续做数据分析。

当我刚接触 Python 时,我已经被 Python 深深所吸引。Python 吸引我的地方不仅仅能用其编写网络爬虫,而且能用于数据分析。我能将大量的数据中以图形化方式呈现出来,更加直观的解读数据。

数据分析的前提是有数据可分析。如果没有数据怎么办?一是可以去一些数据网站下载相关的数据,不过数据内容可能不是自己想要的。二是自己爬取一些网站数据。

今天,我就爬取全国各地所有的必胜客餐厅信息,以便后续做数据分析。

01抓取目标

我们要爬取的目标是必胜客中国。打开必胜客中国首页,进入“餐厅查询”页面。

100行代码爬取全国所有必胜客餐厅信息

我们要爬取的数据内容有城市、餐厅名字、餐厅地址以及餐厅联系电话。因为我看到页面中有地图,所以页面一定有餐厅地址的经纬度。因此,餐厅的经纬度也是我们需要爬取的数据。

至于全国有必胜客餐厅的城市列表,我们可以通过页面的“切换城市”获取。

100行代码爬取全国所有必胜客餐厅信息

02分析目页面

在编写爬虫程序之前,我都是先对页面进行简单分析,然后指定爬取思路。而且对页面结构进行分析往往会有一些意想不到的收获。

我们使用浏览器的开发者工具对页面结构进行简单分析。

100行代码爬取全国所有必胜客餐厅信息

我们在 StoreList 页面中能找到我们所需的数据。这个能确定数据提取的 Xpath 语法。

StoreList 页面的 Response 内容比较长。我们先不着急关闭页面,往下看看,找找看是否有其他可利用的内容。***,我们找到调用获取餐厅列表信息的 JavaScript 函数代码。

100行代码爬取全国所有必胜客餐厅信息

我们接着搜索下GetStoreList函数,看看浏览器如何获取餐厅列表信息的。

100行代码爬取全国所有必胜客餐厅信息

从代码中,我们可以了解到页面使用 Ajax 方式来获取数据。页面以 POST 方式请求地址http://www.pizzahut.com.cn/StoreList/Index。同时,请求还携带参数 pageIndex 和 pageSize。

03爬取思路

经过一番页面结构分析之后,我们指定爬取思路。首先,我们先获取城市信息。然后将其作为参数,构建 HTTP 请求访问必胜客服务器来获取当前城市中所有餐厅数据。

为了方便数据爬取,我将所有城市全部写入到 cities.txt 中。等要爬取数据时,我们再从文件中读取城市信息。

爬取思路看起来没有错,但是还是有个难题没有搞定。我们每次打开必胜客的官网,页面每次都会自动定位到我们所在的城市。如果无法破解城市定位问题,我们只能抓取一个城市数据。

于是乎,我们再次浏览首页,看看能不能找到一些可用的信息。最终,我们发现页面的 cookies 中有个 iplocation 字段。我将其进行 Url 解码,得到 深圳|0|0 这样的信息。

100行代码爬取全国所有必胜客餐厅信息

看到这信息,我恍然大悟。原来必胜客网站根据我们的 IP 地址来设置初始城市信息。如果我们能伪造出 iplocation 字段信息,那就可以随便修改城市了。

04代码实现

***步是从文件中读取城市信息。

 

  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 列表,将每个城市作为参数,构造 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 去请求必胜客服务器。***再对返回页面数据进行提取。

  1. def get_stores(city, count): 
  2.     """ 根据城市获取餐厅信息 """ 
  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 字段,设置自己想要抓取城市。 
  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.             # 过滤掉括号和后面的内容 
  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 

第三步是将城市以及城市所有餐厅信息等数据写到 Json 文件中。

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

05爬取结果

程序运行完之后, 就会在当前目录下生成一个名为「results.json」文件。完整代码请见GitHub:

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

100行代码爬取全国所有必胜客餐厅信息

关于作者:极客猴,热衷于 Python,目前擅长利用 Python 制作网络爬虫以及 Django 框架。

责任编辑:未丽燕 来源: Python中文社区
相关推荐

2018-12-10 15:53:41

Python必胜客数据分析

2023-04-11 22:03:36

2017-08-01 17:02:19

代码Python数据

2023-05-04 07:34:37

Rust代码CPU

2021-12-16 06:21:16

React组件前端

2017-02-08 14:16:17

C代码终端

2017-11-17 19:56:46

爬虫视频信息数据库

2023-11-27 07:10:06

日志中间件

2020-08-21 13:40:17

Python代码人体肤色

2018-01-10 22:19:44

2020-03-26 12:38:15

代码节点数据

2015-02-09 10:43:00

JavaScript

2019-05-05 09:46:01

Python代码神经网络

2020-12-07 10:59:01

Python数据工具

2015-09-01 16:26:18

Linux内核

2020-07-20 09:20:48

代码geventPython

2023-02-01 22:40:38

shellDocker

2020-07-15 09:40:37

代码Python浏览记录

2013-09-09 10:52:10

2015-10-10 14:33:55

点赞
收藏

51CTO技术栈公众号