几种方式保存爬虫爬取的数据 - Python

以美团烤肉为例,将爬取的数据进行保存。

第一种:csv。

新建一个csv文档,利用字典写入器写入头,然后把爬取好的数据进行字典构造,然后将字典逐条写入到csv文档里。

 1 """
 2     爬取美团烤肉
 3 """
 4 import pprint
 5 import csv
 6 import parsel
 7 import requests
 8 import json
 9 
10 f = open('美团烤肉.csv', mode='a', encoding='utf-8-sig', newline='')
11 csvWriter = csv.DictWriter(f, fieldnames=[
12         '商铺id',
13         '商铺名称',
14         '烤肉类型',
15         '评论人数',
16         '平均消费',
17         '商铺评分',
18         '所在商圈',
19         '详情页',
20 ])
21 csvWriter.writeheader() # 写入头
22 
23 headers = {
24     'referer':'https://xxz.meituan.com/', # 这个叫防盗链,也叫来路,没有这个可能不会返回正常的json数据
25     'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36',
26 }
27 
28 
29 for page in range(32, 620 + 1, 32):
30 # 原始请求url= https://apimobile.meituan.com/group/v4/poi/pcsearch/110?uuid=f7325d6be06f44019907.1639106132.1.0.0&userid=394536385&limit=32&offset=64&cateId=-1&q=烤肉&token=mKqO1rGk3adC-dG4fspmVCJj-bgAAAAAhA8AAPVPiOhDFB1UirWrXZHX_ZEM-6qsRE4yHPX1o2RbzI9csT0G-CikXFP8TPrDZj0EwQ
31 # url中?后面的都是参数,下面来构建参数
32     data = {
33         "uuid": "faf0.0",
34         "userid": "39e",
35         "limit": "32",
36         "offset": page,
37         "cateId": "-1",
38         "q": "烤肉",
39         "token": "xx",
40     }
41     url = 'https://apimobile.meituan.com/group/v4/poi/pcsearch/110'
42     # 构建好了参数,也有url,下面带参数进行请求
43     response = requests.get(url=url, headers=headers, params=data) # 携带参数是params,而不是data
44     results = response.json()['data']['searchResult']
45     pprint.pprint(results)
46     for item in results:
47         shopId = item['id'] # 店铺id,用于构建详情页
48         shopName = item['title'] # 店名
49         comment = item['comments'] # 评论数
50         commentScore = item['avgscore'] # 评分
51         averagePrice = item['avgprice'] # 均价
52         shopStyle = item['backCateName'] # 烤肉类型
53         areaName = item['areaname'] # 所在地区
54         detailPage = 'https://www.meituan.com/meishi/' + str(shopId)
55 
56         # if detailPage: # 如果有详情页,就把电话和地址还有营业时间提取出来
57         #     res = requests.get(url=detailPage, headers=headers)
58         #     print(res.text)
59         #     selector = parsel.Selector(res.text) # 用parsel解析
60         #     lis = selector.css('.address')
61         #     for li in lis:
62         #         address = li.css('p:nth-child(1)::text').get()
63         #         telephone = li.css('p:nth-child(2)::text').get()
64         #         businessTime = li.css('p:nth-child(3)::text').get()
65         print(shopId, shopName, shopStyle, comment, averagePrice, commentScore, areaName, detailPage, sep=' | ')
66         dit = {
67             '商铺id': shopId,
68             '商铺名称': shopName,
69             '烤肉类型': shopStyle,
70             '评论人数':comment,
71             '平均消费': averagePrice,
72             '商铺评分': commentScore,
73             '所在商圈': areaName,
74             '详情页': detailPage,
75         }
76         csvWriter.writerow(dit) # 写入数据
77 f.close() # 关闭文档

第二种:excel,利用openpyxl将数据保存成.xlsx格式的。

利用openpyxl创建一个工作簿,在工作簿里新建工作表,利用行列标签写入表头。然后将采集好的数据,逐条追加到表格。

 1 import random
 2 import time
 3 import openpyxl
 4 import json
 5 import requests
 6 
 7 wb = openpyxl.Workbook() # 新建工作簿
 8 ws = wb.create_sheet(index=0) # 新建工作表
 9 
10 # 写入头
11 ws.cell(row=1, column=1, value='商铺id') # 第一行第一列写入商铺id
12 ws.cell(row=1, column=2, value='商铺名称') # 第一行第二列写入商铺名称
13 ws.cell(row=1, column=2, value='烤肉类型') # 第一行第二列写入商铺名称
14 ws.cell(row=1, column=2, value='评论人数') # 第一行第二列写入商铺名称
15 ws.cell(row=1, column=2, value='平均消费') # 第一行第二列写入商铺名称
16 ws.cell(row=1, column=2, value='商铺评分') # 第一行第二列写入商铺名称
17 ws.cell(row=1, column=2, value='所在商圈') # 第一行第二列写入商铺名称
18 ws.cell(row=1, column=2, value='详情页') # 第一行第二列写入商铺名称
19 
20 #  数据爬取部分
21 headers = {
22     'referer':'https://xx.meituan.com/', # 这个叫防盗链,也叫来路,没有这个可能不会返回正常的json数据
23     'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36',
24 }
25 headersfordetailPage = {
26     'cookie':'cookie',
27     'referer':'https://xx.meituan.com/', # 这个叫防盗链,也叫来路,没有这个可能不会返回正常的json数据
28     'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36',
29 }
30 for page in range(32, 640 + 1, 32):
31     time.sleep(random.uniform(2, 5))
32     data = {
33             "uuid": "efea",
34             "userid": "fafa",
35             "limit": "32",
36             "offset": page,
37             "cateId": "-1",
38             "q": "烤肉",
39             "token": "afaf",
40         }
41     url = 'https://apimobile.meituan.com/group/v4/poi/pcsearch/110'
42     # 请求数据
43     response = requests.get(url=url, headers=headersfordetailPage, params=data)
44     # 获取返回数据
45     results = response.json()['data']['searchResult'] # 找到需要的数据
46     for item in results:
47         shopId = item['id'] # 店铺id,用于构造详情页
48         shopName = item['title']  # 店名
49         comment = item['comments']  # 评论数
50         commentScore = item['avgscore']  # 评分
51         averagePrice = item['avgprice']  # 均价
52         shopStyle = item['backCateName']  # 烤肉类型
53         areaName = item['areaname']  # 所在地区
54         detailPage = 'https://www.meituan.com/meishi/' + str(shopId)
55 
56         print(shopId, shopName, comment, commentScore, averagePrice, shopStyle, areaName, detailPage, sep=" | ")
57         ws.append([shopId, shopName, comment, commentScore, averagePrice, shopStyle, areaName, detailPage]) # 写入到表格
58 
59 wb.close() # 关闭文档

第三种,使用pandas保存数据到本地,可以是csv文件也可以是xlsx文件。

 1 import random
 2 import time
 3 
 4 import pandas as pd
 5 import requests
 6 import json
 7 
 8 df = pd.DataFrame() # DataFrame数据格式,用于保存到本地
 9 
10 headers = {
11     'referer':'https://qz.meituan.com/', # 这个叫防盗链,也叫来路,没有这个可能不会返回正常的json数据
12     'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36',
13 }
14 
15 for page in range(32, 640 + 1, 32):
16     print(f'-------------------------正在爬取第{int(page/32)}页数据------------------------------')
17     time.sleep(random.uniform(2,5)) # 随机休眠
18     # 请求参数
19     data = {
20         "uuid": "id",
21         "userid": "fd",
22         "limit": "32",
23         "offset": page,
24         "cateId": "-1",
25         "q": "烤肉",
26         "token": "ddd",
27     }
28     # 请求网址
29     url = 'https://apimobile.meituan.com/group/v4/poi/pcsearch/110'
30     # 开始请求数据
31     response = requests.get(url=url, headers=headers, params=data) # 带参数请求网页
32     results = response.json()['data']['searchResult'] #  取到列表数据
33     for item in results:
34         shopId = item['id']  # 店铺id,用于构造详情页
35         shopName = item['title']  # 店名
36         comment = item['comments']  # 评论数
37         commentScore = item['avgscore']  # 评分
38         averagePrice = item['avgprice']  # 均价
39         shopStyle = item['backCateName']  # 烤肉类型
40         areaName = item['areaname']  # 所在地区
41         detailPage = 'https://www.meituan.com/meishi/' + str(shopId)
42         print(shopId, shopName, comment, commentScore, averagePrice, shopStyle, areaName, detailPage, sep=" | ")
43         data = pd.DataFrame({'商铺id':[shopId], '商铺名称':[shopName], '评论人数':[comment], '平均评分':[commentScore],
44                              '平均价格':[averagePrice], '烤肉类型':[shopStyle], '商铺商圈':[areaName], '详情页':[detailPage]})
45         df = pd.concat([df, data]) # 连接数据
46 # df.to_csv('美团烤肉pd.csv', encoding='utf-8-sig', index=False, mode='a') # 保存到csv
47 df.to_excel('美团烤肉pd.xlsx', encoding='utf-8-sig', index=False) # 保存到excel

第四种,保存到MySql数据库:

首先在服务器创建数据库,我一般用phpmyadmin控制台和navicat创建数据库。新建数据库的时候,最好用navicat新建,选的字符utf8 -- UTF-8 Unicode,在phpmyadmin里建utf8_general_ci字符集。

 创建完数据库后进行数据表设计,表名为meituandata。字段为店铺id,店铺名,评论人数,平均评分,平均消费,烤肉类型,所在商圈,详情页,sql语句如下:

 1 CREATE TABLE `20211214meituan`.`meituandata` 
 2     ( 
 3     `id` INT NOT NULL AUTO_INCREMENT COMMENT '自增id' , 
 4     `shopId` INT NOT NULL COMMENT '商铺id' , 
 5     `shopName` VARCHAR(30) NOT NULL COMMENT '商铺名' , 
 6     `commentCount` INT NOT NULL COMMENT '评论人数取整数' , 
 7     `avgScore` FLOAT NOT NULL COMMENT '平均分' , 
 8     `avgPrice` DECIMAL NOT NULL COMMENT '消费均价' , 
 9     `shopStyle` VARCHAR(30) NOT NULL COMMENT '烤肉类型' , 
10     `shopArea` VARCHAR(255) NOT NULL COMMENT '所在商圈' , 
11     PRIMARY KEY (`id`)
12     ) ENGINE = MyISAM;

创建完后发现少了一个字段,在加一个字段,sql语句:

1 ALTER TABLE `meituandata` ADD `detailPage` VARCHAR(255) NOT NULL AFTER `shopArea`;

爬虫加保存代码:

 1 import random
 2 import time
 3 import requests
 4 import json
 5 import pymysql
 6 
 7 # 首先是爬虫
 8 headers = {
 9     'cookie':'YourCookie',
10     'referer':'https://xx.meituan.com/',
11     'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36',
12 }
13 
14 for offset in range(0, 640 + 1, 32): #
15     data = {
16         "uuid": "YourId",
17         "userid": "Id",
18         "limit": "32",
19         "offset": offset,
20         "cateId": "-1",
21         "q": "keywords",
22         "token": "YourToken",
23     }
24     # 美团的数据也是存储在json里的,只是前两页没有数据
25     time.sleep(random.uniform(2,8))
26     url = 'https://apimobile.meituan.com/group/v4/poi/pcsearch/110'
27     response = requests.get(url=url, headers=headers,params=data)
28     # print(response.json())
29     # 从json中获取我们要的结果
30     results = response.json()['data']['searchResult'] # 结果
31     for item in results:
32         shopId = int(item['id']) # 商铺id
33         shopName = str(item['title']) # 商铺名字
34         commentCount = int(item['comments']) # 评论数
35         avgCommentScore = float(item['avgscore']) # 店铺评论平均分
36         avgPrice = float(item['avgprice']) # 店铺人均消费
37         shopStyle = str(item['backCateName']) # 烤肉类型
38         shopArea = str(item['areaname']) # 店铺商圈
39         detailPage = 'https://www.meituan.com/meishi/{}/'.format(shopId)
40         print(shopId, shopName, commentCount, avgCommentScore, avgPrice, shopStyle, shopArea, detailPage, sep=' | ')
41         # 定义数据库常数
42         # host = '127.0.0.1'  # 数据库服务器地址
43         # user = 'root'  # 数据库用户名
44         # pwd = ''  # 数据库密码
45         # dbname = 'meituan',  # 数据库名称
46         # 开始连接数据库
47         database = pymysql.connect(host='127.0.0.1', user='root', password='', database='meituan', charset='utf8')
48         # 建立游标对象
49         cursor = database.cursor()
50         # sql语句
51         sql = "INSERT INTO meituandata (shopId, shopName, commentCount, avgScore, avgPrice, shopStyle, shopArea, detailPage) " \
52           "VALUES ('{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}');".format(shopId, shopName, commentCount, avgCommentScore, avgPrice, shopStyle, shopArea, detailPage)
53         # 执行sql语句
54         cursor.execute(sql)
55         # 执行数据库更改
56         database.commit()
57 database.close() # 在所有数据写入之后关闭数据库

程序运行结果截图:

 数据保存记录截图:

 总结几个坑:

  1,爬虫呢,如果找不到动态数据,可以用selenium进行渲染网页后进行提取信息;

  2,sql语句与python结合呢,不能用f"stringxxxxx",只能用"stringxxxx{}".format(),要不然sql语句会一直报错,1064最多,1064是语法错误;

  3,用pymysql连接数据库的时候,charset是utf8,不是utf-8;

  4,做爬虫已经很惹人厌了,本人提倡请求页面的时候有时间间隔,给服务器减压。

  5,最后,本文仅供学习交流使用,也是本人的笔记之一,如有疑问,请与我联系,我将即时处理。

posted @ 2021-12-10 15:24  、一叶孤城  阅读(3215)  评论(0编辑  收藏  举报