python爬取美團評論做詞雲分析

前言: 這是一個幫忙做的畢業論文設計相關的爬蟲,爬取美團的評論後,進行詞雲分析,倒是不復雜,我花半個小時寫好了爬蟲相關的代碼,然後又花了近兩個小時錄製了教程視頻,如果大家想看的話,等我到學校有網絡了,可以發給大家學習,這個視頻由於在錄製的過程收到了干擾,分爲了4個部分,分別爲(抓包分析,美團爬蟲,IP代理,詞雲流程),裏面都是我個人積累的爬蟲實戰經驗,可以作爲一個很好的入門項目。


開發環境: window10,python37,jupyter notebook
爬取結果及流程文檔下載: https://www.lanzous.com/i9m0sfe

1、抓包分析

1.1、分析網頁

對於網絡爬蟲,我拿到的第一件事就是分析它的網頁數據的加載方式,再決定我請求服務器的方式。

在這裏插入圖片描述

  1. 從上面的文字看出,它並沒有對字體進行加密,這樣我們就省心一點兒了。
  2. 它的這些評論都可以直接查看,不需要登陸,這樣的話反爬措施又少了一層。
  3. 點擊下一頁,它的URL並沒有發生變化,可以初步判斷它是ajax加載的數據,所以我們可以抓包來看看了。

1.2、如何進行抓包?

瀏覽器的中的每一條信息的加載都離不開 Network ,這就意味着我們可以通過它來查看網頁加載出來的內容。

抓包的步驟:

  1. 鼠標右擊,打開檢查功能
  2. 選擇Network
  3. 選擇All
  4. 刷新網頁
  5. 查看加載的數據

在這裏插入圖片描述
如何更好的查看加載的內容是什麼?

  1. 我們的目的只是找到自己需要的內容,沒有必要全部都查看一遍,只需要知道一些關鍵的數據進行查看就好了。
    最重要的是注意 Network 中的Type(加載的文件類型) 和 size(加載的文件大小) 這兩個要素,如我們要查看的目標是文字文件,帶有圖片類型的文件都可以不用查看了,其二就是它的大小,上面的很多文件都沒有顯示大小,我們幾乎可以把它忽略了。對於網頁不是很瞭解的同學,不建議直接使用篩選功能。

  2. 查看內容:
    在這裏插入圖片描述
    也可以把這些信息複製到一個json數據解析的網站上解析一下,就可以看到格式化的內容了。

  3. 從上面信息中,可以發現一共有10個用戶在評論,說明每次它只加載10個評論與回覆。

  4. 我們再來看它請求數據的方式,把它點在headers這裏查看它的請求頭
    在這裏插入圖片描述
    注意看這上面的信息,完全和它這個路徑的信息相同,我們把這個鏈接複製到瀏覽器打開試試
    在這裏插入圖片描述

  5. 如果出現了這樣的結果,說明這個鏈接已經自帶請求參數了,這樣我們就方便很多了,可以直接拿來就用。

  6. 現在點擊第二頁,找到它的這個路徑,複製過來,粘貼到編輯器裏,然後再點擊下一頁,複製第三來進行對比
    在這裏插入圖片描述
    從上面的結果發現,它們的參數只有 offset= 不同,並且間隔爲10,接下來我們直接生成對應的這個數據通道就ok了。

  7. 這樣抓包就算完成了,接下了就可以請求服務器,提取數據了。


2、美團爬蟲

2.1、如何提取json()數據?

json數據的模塊擁有包含關係,它們的級別可以互相包含,擁有層次感,如:
在這裏插入圖片描述
具體提取和美化的方法可以轉至我的另一篇博客學習 python爬蟲爬取微博之戰疫情用戶評論及詳情

2.2、正式爬取信息

import requests
from fake_useragent import UserAgent
for page in range(0, 371, 10):#0~100
    url = "https://www.meituan.com/meishi/api/poi/getMerchantComment?uuid=2ff7056c-9d76-424c-b564-b7084f7e16e4&platform=1&partner=126&originUrl=https%3A%2F%2Fwww.meituan.com%2Fmeishi%2F193383554%2F&riskLevel=1&optimusCode=10&id=193383554&userId=&offset={}&pageSize=10&sortType=1".format(page)  
    headers = {
    "User-Agent" : UserAgent().chrome #chrome瀏覽器隨機代理
    }
    respone = requests.get(url = url, headers = headers) #向服務器發出請求,服務器返回結果
    for item in respone.json()['data']['comments']:#遍歷,循環
        userId = item['userId']
        userName = item['userName']
        avgPrice = item['avgPrice']
        comment = item['comment']
        merchantComment = item['merchantComment']
        data = (userId, userName, avgPrice, comment, merchantComment)
        print (data)  

爬取到幾條以後,它就這樣報錯了:
在這裏插入圖片描述
突然間就說找不到 data 了,這是爲什麼呢?來打印一下我們最後這一次請求看看結果:
在這裏插入圖片描述
正常情況下,不可能上一個還是正常的,下一個網絡就有問題的,推斷應該是服務器已經識別出來這是一個爬蟲程序在向它發起的請求,我們再來瀏覽器中打開它評論的這個頁面來看看,發現它出現了一個驗證碼,我們輸入驗證碼後重新請求,程序又可以正常跑一會兒,然後就會掛掉,估計是它禁止某個IP不斷的訪問它的信息,接下來去弄一堆 IP 代理來訪問它試試


3、IP代理

下去爬一個 IP代理網站的 IP來供我們使用代理,具體方法可以到 學習python爬蟲看一篇就足夠了之爬取《太平洋汽車》論壇及點評實戰爬蟲大全 觀看 第3部分:requests + IP代理 ,我在這裏有詳細的介紹,這個代碼也是直接從那裏複製過來的。

3.1、爬取存入CSV代碼彙總

# https://www.meituan.com/meishi/193383554/ 商品鏈接

import requests, json, re, random, time, csv
from fake_useragent import UserAgent

starttime = time.time()#記錄開始時間

ips = [] #裝載有效 IP 
for i in range(1, 6):
    headers = {
    "User-Agent" : UserAgent().chrome #chrome瀏覽器隨機代理
    }
    ip_url = 'http://www.89ip.cn/index_{}.html'.format(i)
    html = requests.get(url=ip_url, headers=headers).text
    res_re = html.replace(" ", "").replace("\n", "").replace("\t", "")
    #使用正則表達式匹配出IP地址及端口
    r = re.compile('<tr><td>(.*?)</td><td>(.*?)</td><td>')
    result = re.findall(r, res_re)
    for i in range(len(result)):
        ip = "http://" + result[i][0] + ":" + result[i][1]
        # 設置爲字典格式
        proxies = {"http": ip}
        #使用上面的IP代理請求百度,成功後狀態碼200
        baidu = requests.get("https://www.baidu.com/", proxies = proxies)
        if baidu.status_code == 200:        
            ips.append(proxies)
    print ("正在準備IP代理,請稍後。。。")

#創建CSV文件,並寫入表頭信息,並設置編碼格式爲“utf-8-sig”防止中文亂碼
fp = open('./美團_大學城.csv','a', newline='',encoding='utf-8-sig') #"./"表示當前文件夾,"a"表示添加
writer = csv.writer(fp) #方式爲寫入
writer.writerow(('用戶ID','用戶名', '平均價','評論','回覆')) #表頭

for page in range(0, 371, 10):#0~100
    url = 'https://www.meituan.com/meishi/api/poi/getMerchantComment?uuid=9f45527e-2983-40c9-bc92-f58a8290c947&platform=1&partner=126&originUrl=https%3A%2F%2Fwww.meituan.com%2Fmeishi%2F193383554%2F&riskLevel=1&optimusCode=10&id=193383554&userId=&offset={}&pageSize=10&sortType=1'.format(page)
    try:  
        headers = {
             "User-Agent" : UserAgent().chrome #chrome瀏覽器隨機代理
        }
        rep = requests.get(url=url, headers=headers, proxies=ips[random.randint(0 , len(ips)-1)])
        print ("爬取條數:", page)
        for info in rep.json()['data']['comments']:
            userId = info['userId']
            userName = info['userName']
            avgPrice = info['avgPrice']
            comment = info['comment']
            merchantComment = info['merchantComment']
            data = (userId, userName, avgPrice, comment, merchantComment)
            writer.writerow((data))            
    except:
        print ("這裏發生異常:", url)
        pass
fp.close() #關閉文件
endtime = time.time()#獲取結束時間
sumTime = endtime - starttime #總的時間
print ("一共用的時間是%s秒"%sumTime)

在這裏插入圖片描述
在這裏插入圖片描述

3.1、爬取存入TXT代碼彙總

# https://www.meituan.com/meishi/193383554/
import requests,json
from fake_useragent import UserAgent
import requests,re,random
from lxml import etree
from fake_useragent import UserAgent

ips = [] #建立數組,用於存放有效IP
for i in range(1,6):
    print ("正在準備IP代理,請稍等。。。")
    headers = {
    "User-Agent" : UserAgent().chrome #chrome瀏覽器隨機代理
    }
    ip_url = 'http://www.89ip.cn/index_%s.html'%i
    # 請求IP的網站,得到源碼
    res = requests.get(url=ip_url, headers=headers).text
    res_re= res.replace('\n', '').replace('\t','').replace(' ','')
    # 使用正則表達匹配出IP地址及它的端口
    re_c = re.compile('<tr><td>(.*?)</td><td>(.*?)</td><td>')
    result = re.findall(re_c, res_re)
    for i in range(len(result)):
    	#拼接出完整的IP
        ip = 'http://' + result[i][0] + ':' + result[i][1]
        # 設置爲字典格式
        proxies={"http":ip}
        #使用上面爬取的IP代理請求百度
        html = requests.get('https://www.baidu.com/', proxies=proxies)
        if html.status_code == 200: #狀態碼爲200,說明請求成功
            ips.append(proxies) #添加進數組中
            
headers = {
"User-Agent" : UserAgent().chrome #chrome瀏覽器隨機代理
}
for page in range(0,371, 10):    
    url = 'https://www.meituan.com/meishi/api/poi/getMerchantComment?uuid=9f45527e-2983-40c9-bc92-f58a8290c947&platform=1&partner=126&originUrl=https%3A%2F%2Fwww.meituan.com%2Fmeishi%2F193383554%2F&riskLevel=1&optimusCode=10&id=193383554&userId=&offset={}&pageSize=10&sortType=1'.format(page)
    try:
        rep = requests.get(url=url, headers=headers, proxies=ips[random.randint(0 , len(ips)-1)])
        print ("爬取條數:", page)
        for info in rep.json()['data']['comments']:
            with open("./美團文本.txt", "a", encoding='utf-8') as f:
                comment = str(info['comment'])#評論
                merchantComment = str(info['merchantComment'])#商家回覆
                f.write(comment)
                f.write(merchantComment)
                f.close()
    except:
        pass

在這裏插入圖片描述

4、詞雲流程

4.1、打開txt文本做詞雲圖

# 導入包
import jieba #pip install jieba
from wordcloud import WordCloud #pip install wordcloud

4.1.1、對jieba分詞的簡單瞭解

精準模式:

#精準模式
cut_text = jieba.cut("信息管理與信息系統", cut_all=False) #False,精準;True,全能
cut_text = ' '.join(cut_text)
cut_text
'信息管理 與 信息系統'

全能模式:

cut_text = jieba.cut("信息管理與信息系統", cut_all=True) #False,精準;True,全能
cut_text = ' '.join(cut_text)
cut_text

4.1.2、詞雲基礎

f = open("./美團文本.txt", "r", encoding="utf-8") #打開一個文本
txt = f.read()#讀取文本內容
cut_text = jieba.cut(txt, cut_all=False) #False,精準;True,全能。# 結果爲數組
cut_text = ' '.join(cut_text) #把數組拼接爲字符串

word_cloud = WordCloud(font_path="C:/Windows/Fonts/simhei.ttf",
             background_color="white",#背景
             max_words=800, #畫布字體個數
             max_font_size=180,#最大字體
             min_font_size=40,#最小字體
             width=1920,
             height=1080).generate(cut_text)#傳入分詞文本
#定義圖片的畫布
plt.figure(figsize=(16, 9))#設置畫布大小
plt.imshow(word_cloud, interpolation="bilinear")
plt.axis("off")
word_cloud.to_file('output.png')#保存圖片
plt.show()#展示圖片

在這裏插入圖片描述

4.1.3、加入背景圖片

在這裏插入圖片描述

from wordcloud import WordCloud #導入詞雲庫 pip install wordcloud
from wordcloud import ImageColorGenerator # 獲取圖片像素值
from matplotlib.image import imread #讀取圖片 #pip install matplotlib
import matplotlib.pyplot as plt #顯示圖片 
import jieba.analyse #結巴分析,#pip install jieba

back_img = imread("bg_pic1.jpg") #讀取圖片
img_colors = ImageColorGenerator(back_img) # 生成圖片的像素值

file = open("./美團文本.txt", encoding="utf-8")#打開一個文本
txt = file.read()#讀取內容

# 第一個參數:待提取關鍵詞的文本
# 第二個參數:返回關鍵詞的數量,重要性從高到低排序
# 第三個參數:是否同時返回每個關鍵詞的權重
# 第四個參數:詞性過濾,爲空表示不過濾,若提供則僅返回符合詞性要求的關鍵詞,allowPOS=('ns', 'n', 'vn', 'v')表示選取地名、名詞、動名詞、動詞
tags = jieba.analyse.extract_tags(txt, topK = 1000, withWeight = True, allowPOS=()) #使用結巴分析提取標籤
data = {item[0]: item[1] for item in tags}#tags是數組形式,把數組轉爲詞頻字典

word_cloud = WordCloud(font_path="c:\windows\Fonts\simhei.ttf",#字體,本電腦c盤下的黑體,這樣才能顯示中文
                       background_color="white",#圖片的背景顏色
                       max_words=1000,#字體個數,不超過上面選取的個數
                       max_font_size=100,#字體大小
                       width=1920,#圖片像素寬
                       mask=back_img,#使用圖片蒙板,上面讀取圖片的像素
                       height=1080).generate_from_frequencies(data)#傳入上面的詞頻結果

file.close()#關閉上面打開的文件
wc_color = word_cloud.recolor(color_func=img_colors)  # 替換默認的字體顏色

plt.figure(figsize=(12, 12))  # 創建一個圖形實例,設置畫布大小
plt.imshow(word_cloud, interpolation='bilinear')#插值='雙線性'
plt.axis("off")  # 不顯示座標尺寸
word_cloud.to_file('output1.png')#保存圖片
plt.show()

在這裏插入圖片描述

4.2、打開CSV文本做詞雲圖

我們在做詞雲圖的時候,是對文本進行分詞,再統計詞頻;對於儲存在表格中的數據,我們可以先把它提取出來,再進行上面的操作就可以了.

#導入相關的包
import pandas as pd #導入pandas命名爲pd #pip install pandas
from wordcloud import WordCloud #導入詞雲庫 pip install wordcloud
from wordcloud import ImageColorGenerator # 獲取圖片像素值
from matplotlib.image import imread #讀取圖片 #pip install matplotlib
import matplotlib.pyplot as plt #顯示圖片 
import jieba.analyse #結巴分析,#pip install jieba

4.2.1、導入數據

data = pd.read_csv("./美團_大學城.csv")#打開csv文件
data #運行可以直接顯示錶格

4.2.2、讀取表格中的評論文本

在這裏插入圖片描述

4.2.2.1、單獨把文本讀取出來

for pl in data['評論']:
    print (pl)

在這裏插入圖片描述

4.2.2.2、數據清洗

  • str(pl) 把pl轉化爲字符串
  • strip() 移除首尾的空格
  • replace(“nan”, “”) 替換掉空值nan
  • replace("\n", “”) 替換掉換行符
for pl in data['評論']:
    comment = str(pl).strip().replace("nan", "").replace("\n", "")
    print (comment)

在這裏插入圖片描述

4.3、轉化爲文本

  • 創建一個空數組存遍歷出來的評論和回覆的信息
txts = [] #裝所有的評論和回覆
txts = []
for pl in data['評論']:
    txts.append(str(pl).strip().replace("nan", "").replace("\n", ""))
    
for hf in data['回覆']:
    txts.append(str(hf).strip().replace("nan", "").replace("\n", ""))
    
#把上面的評論和回覆轉化成字符串
text = ' '.join(txts) #數組轉字符串拼接的方法
print (text)

**加粗樣式**![

  • 現在的文本已經去掉了換行和間隔, 可以直接使用上面的方法生成詞雲圖了, 文本數據就在text中
from wordcloud import WordCloud #導入詞雲庫 pip install wordcloud
from wordcloud import ImageColorGenerator # 獲取圖片像素值
from matplotlib.image import imread #讀取圖片 #pip install matplotlib
import matplotlib.pyplot as plt #顯示圖片 
import jieba.analyse #結巴分析,#pip install jieba

back_img = imread("bg_pic1.jpg") #讀取背景圖片
img_colors = ImageColorGenerator(back_img) # 生成圖片的像素值

# 第一個參數:待提取關鍵詞的文本
# 第二個參數:返回關鍵詞的數量,重要性從高到低排序
# 第三個參數:是否同時返回每個關鍵詞的權重
# 第四個參數:詞性過濾,爲空表示不過濾,若提供則僅返回符合詞性要求的關鍵詞,allowPOS=('ns', 'n', 'vn', 'v')表示選取地名、名詞、動名詞、動詞
tags = jieba.analyse.extract_tags(text, topK = 1000, withWeight = True, allowPOS=()) #使用結巴分析提取標籤
data = {item[0]: item[1] for item in tags}#tags是數組形式,把數組轉爲詞頻字典

word_cloud = WordCloud(font_path="c:\windows\Fonts\simhei.ttf",#字體,本電腦c盤下的黑體,這樣才能顯示中文
                       background_color="white",#圖片的背景顏色
                       max_words=1000,#字體個數,不超過上面選取的個數
                       max_font_size=100,#字體大小
                       width=1920,#圖片像素寬
                       mask=back_img,#使用圖片蒙板,上面讀取圖片的像素
                       height=1080).generate_from_frequencies(data)#傳入上面的詞頻結果

wc_color = word_cloud.recolor(color_func=img_colors)  # 替換默認的字體顏色

plt.figure(figsize=(12, 12))  # 創建一個圖形實例,設置畫布大小
plt.imshow(word_cloud, interpolation='bilinear')#插值='雙線性'
plt.axis("off")  # 不顯示座標尺寸
word_cloud.to_file('output1.png')#保存圖片
plt.show()

在這裏插入圖片描述

詞雲所用的數據全部來自於上面的爬蟲,結果和 html流程文檔 已經全部放在上面的鏈接中,需要的話可以自行下載使用

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章