幾種方式保存爬蟲爬取的數據 - 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,最后,本文僅供學習交流使用,也是本人的筆記之一,如有疑問,請與我聯系,我將即時處理。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM