??本次爬蟲(chóng)項(xiàng)目將會(huì)爬取攜程網(wǎng)中關(guān)于“周莊古鎮(zhèn)”的點(diǎn)評(píng)他炊,然后對(duì)這些評(píng)論進(jìn)行中文分詞及預(yù)處理争剿,形成一張關(guān)于“周莊古鎮(zhèn)”的詞云圖,得到可視化的分析結(jié)果痊末。
項(xiàng)目介紹
??馬上要到中秋啦蚕苇,正好這幾天在公司不太忙,想著中秋假期即將去周莊旅游凿叠,于是涩笤,筆者心血來(lái)潮地想到,能不能利用爬蟲(chóng)做一些關(guān)于周莊的分析呢盒件?琢磨許久蹬碧,筆者終于有了思路,因此炒刁,本次爬蟲(chóng)的大致思路是這樣的:
- 獲取數(shù)據(jù): 利用爬蟲(chóng)爬取攜程網(wǎng)中關(guān)于周莊的點(diǎn)評(píng)
- 文本預(yù)處理:對(duì)這些評(píng)論進(jìn)行中文分詞以及預(yù)處理
- 可視化分析: 制作詞云圖并分析
??整個(gè)項(xiàng)目的結(jié)構(gòu)如下:
其中恩沽,兩個(gè)Python文件分別為爬蟲(chóng)文件和文本預(yù)處理及制作詞云圖文件,zhouzhuang.csv為爬取的評(píng)論文件翔始,zhouzhuang.txt為結(jié)巴分詞時(shí)添加的詞語(yǔ)文件罗心,simsun.ttc為制作詞云圖時(shí)的字體文件(為了能在詞云圖中正確地顯示中文,你需要這個(gè)字體文件)城瞎。
爬取攜程中的評(píng)論
??首先我們需要獲取數(shù)據(jù)渤闷,即關(guān)于周莊的點(diǎn)評(píng)。筆者選取攜程網(wǎng)中對(duì)“周莊古鎮(zhèn)”的點(diǎn)評(píng)作為項(xiàng)目的數(shù)據(jù)集脖镀,具體網(wǎng)址為:http://you.ctrip.com/sight/zhouzhuang81/109861-dianping.html 飒箭。該網(wǎng)頁(yè)一共有8285條點(diǎn)評(píng),共分415頁(yè)展示认然,每頁(yè)20條評(píng)論补憾,評(píng)論有長(zhǎng)有短,也有圖片卷员,我們只需要評(píng)論中的文字部分盈匾。如下圖所示:
??接下來(lái),筆者利用Python爬取這些網(wǎng)頁(yè)中評(píng)論毕骡,完整的Python代碼(zhouzhuang_comments_scrape.py)如下:
import requests
import pandas as pd
from bs4 import BeautifulSoup
from concurrent.futures import ThreadPoolExecutor, wait, ALL_COMPLETED
# 評(píng)論列表
comments = []
# 提取評(píng)論削饵,傳入?yún)?shù)為網(wǎng)址url
def get_comment(url):
global comments
try:
# 發(fā)送HTTP請(qǐng)求
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 \
(KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36'}
r = requests.get(url=url, headers=headers)
# 解析網(wǎng)頁(yè),定位到評(píng)論部分
soup = BeautifulSoup(r.text, 'lxml')
main_content = soup.find_all('div', class_='comment_single')
# 提取評(píng)論
for para in main_content:
comment = para.find('span', class_='heightbox')
print(comment.text)
comments.append(comment.text.replace('"', ''))
except Exception as err:
print(err)
def main():
# 請(qǐng)求網(wǎng)址(共415個(gè)網(wǎng)頁(yè))
urls = ["http://you.ctrip.com/sight/zhouzhuang81/109861-dianping-p%d.html"%x for x in range(1,416)]
urls[0] = urls[0].replace('-p1', '')
# 利用多線程爬取景點(diǎn)評(píng)論
executor = ThreadPoolExecutor(max_workers=20) # 可以自己調(diào)整max_workers,即線程的個(gè)數(shù)
# submit()的參數(shù): 第一個(gè)為函數(shù)未巫, 之后為該函數(shù)的傳入?yún)?shù)窿撬,允許有多個(gè)
future_tasks = [executor.submit(get_comment, url) for url in urls]
# 等待所有的線程完成,才進(jìn)入后續(xù)的執(zhí)行
wait(future_tasks, return_when=ALL_COMPLETED)
# 創(chuàng)建DataFrame并保存到csv文件
comments_table = pd.DataFrame({'id': range(1, len(comments)+1),
'comments': comments})
comments_table.to_csv(r"./ZhouZhuang/zhouzhuang.csv", index=False)
main()
在這個(gè)爬蟲(chóng)中叙凡,我們利用了concurrent.futures這個(gè)模塊中的多線程來(lái)加速爬取評(píng)論劈伴,同時(shí)將這個(gè)評(píng)論儲(chǔ)存在pandas中的DataFrame中,最后將這些評(píng)論保存為zhouzhuang.csv文件握爷,便于后續(xù)的文本預(yù)處理跛璧。zhouzhuang.csv文件的內(nèi)容如下:
??事實(shí)表明严里,該網(wǎng)站雖然寫(xiě)著有8285條評(píng)論,但csv文件中卻只有3020條評(píng)論追城,而且筆者自己也驗(yàn)證了以下刹碾,大概200頁(yè)之后的網(wǎng)站確實(shí)也沒(méi)評(píng)論了,難道需要其它操作座柱?Anyway迷帜,3千多條評(píng)論足夠了。
文本預(yù)處理
??在這部分色洞,我們只是講解文本預(yù)處理的操作流程戏锹,并不會(huì)給出Python代碼,Python代碼會(huì)在后續(xù)的“制作詞云圖”部分一起給出锋玲,作為一個(gè)完整的Python文件景用。
??文本預(yù)處理的流程如下:
- 利用Pandas讀取評(píng)論的csv文件(zhouzhuang.csv)涵叮;
- 對(duì)該csv文件中的每一條評(píng)論惭蹂,先進(jìn)行中文分詞處理(帶有詞性標(biāo)注),然后去掉特殊字符和標(biāo)點(diǎn)符號(hào)割粮,再去掉常用的停用詞(stopwords)盾碗;
- 對(duì)評(píng)論中的名次及詞性為“非語(yǔ)素字” 的詞語(yǔ)進(jìn)行詞頻統(tǒng)計(jì)。
??我們給出在中文分詞過(guò)程中用到的用戶自己添加的詞語(yǔ)舀瓢,即zhouzhuang.txt中的詞語(yǔ)廷雅,如下:
江南水鄉(xiāng)
江南第一水鄉(xiāng)
沈萬(wàn)三
周莊
蘇州
昆山
紙箱王主題創(chuàng)意園區(qū)
紙箱王
雙橋
沈萬(wàn)三故居
沈廳
古戲臺(tái)
張廳
四季周莊
周莊南湖
富安橋
迷樓
怪樓
貞豐橋
逸飛之家
生命奧秘博物館
貞豐文化街
臺(tái)灣老街
沈萬(wàn)三水冢
太平橋
全福講寺
澄虛道院
周莊舫
葉楚傖故居
牌樓塔影
愛(ài)渡風(fēng)情小鎮(zhèn)
源豐順酒作坊
白蜆湖
周莊博物館
戴宅
福洪橋
萬(wàn)三水上財(cái)?shù)烙?古鎮(zhèn)水巷游
南湖秋月園
全福塔
全福長(zhǎng)橋
蜆江漁唱館
蠟工坊名人蠟像館
畫(huà)家村
大誠(chéng)堂
親親魚(yú)魚(yú)療館
太史淀
周莊綠樂(lè)園
大吉祥文化館
周莊魔城
云海塔
周莊富貴園
永慶庵
舟際皮劃艇俱樂(lè)部
英倫騎士馬術(shù)俱樂(lè)部
網(wǎng)咖
江南第一水鄉(xiāng)
萬(wàn)三蹄髈
朱元璋
5A級(jí)景區(qū)
北宋
元祐元年
萬(wàn)三蹄
江南六大古鎮(zhèn)
完美
月圓之夜
5A級(jí)景區(qū)
萬(wàn)三
平江路
山塘街
同里
萬(wàn)歷年間
萬(wàn)歷
烏鎮(zhèn)
第一水鄉(xiāng)
打call
5A級(jí)旅游景區(qū)
5A景區(qū)
陳逸飛
制作詞云圖
??接下來(lái)就是最后的制作詞云圖部分了,在這兒京髓,我們可以得到關(guān)于“周莊古鎮(zhèn)”的評(píng)論的可視化結(jié)果航缀。
??需要注意的是,你的Python中需要安裝wordcloud模塊堰怨,同時(shí)芥玉,為了能在詞云圖中正常地顯示中文,需要添加一下中文字體庫(kù)备图。具體的制作過(guò)程不再詳述灿巧,筆者這里只給出最簡(jiǎn)單的詞云圖繪制。
??完整的Python代碼(comments_anlysis.py)如下
# -*- coding: utf-8 -*-
import jieba.posseg
import pandas as pd
from collections import defaultdict
import matplotlib.pyplot as plt
from wordcloud import WordCloud
# 詞頻統(tǒng)計(jì)字典
dic = defaultdict(int)
# 對(duì)每條評(píng)論進(jìn)行分詞及預(yù)處理
def cut_word(sentence):
# 去掉句子中的特殊字符及標(biāo)點(diǎn)符號(hào)
sentence = sentence.replace('"', '').replace('\n', '')
biaodian_list = '~揽涮!@#¥%……&*()【】{}:抠藕;‘’“”《》,蒋困。盾似、? -_,./<>;:\'"!$^() ヾ?~≈′'
for biaodian in biaodian_list:
sentence = sentence.replace(biaodian, '')
# 分詞(帶詞性標(biāo)注)
words = jieba.posseg.cut(sentence)
# 常用詞
stop_words = ['的', '我', '你', '他', '她', '它', '我們', '你們', '他們', '她們', '它們', \
'這', '這兒', '那', '那兒', '在', '在哪', '這里', '哪里', '那里', '了', '嗎','啊', \
'是', '不是', '著', '謝謝', '也', '就', '去', '到', '可以', '不', '什么', '會(huì)', \
'再', '哦', '有', '很', '都', '和', '還是', '還', '感覺(jué)', '上', '但', '來(lái)',\
'一個(gè)', '地方', '就是', '里面', '一次', '一些', '這次', '已經(jīng)', '又', '個(gè)', '這個(gè)', \
'那個(gè)', '要', '但是', '里', '看', '住', '讓', '太', '沒(méi)', '說(shuō)', '時(shí)候',\
'小', '大', '還有', '走', '不過(guò)', '比較']
# 只統(tǒng)計(jì)名詞或詞性為x的詞語(yǔ)
for word in words:
# 去掉句子中的常用詞
if word.word not in stop_words:
# 判斷是否為名詞
if 'n' in word.flag or 'x' in word.flag:
word = word.word # 取出該名詞
print(word)
dic[word] += 1
def main():
jieba.load_userdict(r'./Zhouzhuang/zhouzhuang.txt')
# 讀取評(píng)論csv文件并進(jìn)行分詞,預(yù)處理雪标,統(tǒng)計(jì)詞頻操作
df = pd.read_csv(r'./Zhouzhuang/zhouzhuang.csv', encoding='utf-8')
df['comments'].apply(lambda x: cut_word(x))
# 對(duì)詞語(yǔ)進(jìn)行排序
sort_dict = sorted(dic.items(), key=lambda x: x[1], reverse=True)
# print(sort_dict)
wl_space_split = []
for i in range(40):
print(sort_dict[i])
for _ in range(sort_dict[i][1]):
wl_space_split.append(sort_dict[i][0])
# 產(chǎn)生詞云圖并顯示
my_wordcloud = WordCloud(font_path=r"./Zhouzhuang/simsun.ttc", background_color='white')\
.generate(" ".join(wl_space_split))
plt.imshow(my_wordcloud)
plt.axis("off")
plt.show()
main()
??最高頻的40個(gè)詞語(yǔ)如下:
('周莊', 2375)
('古鎮(zhèn)', 1187)
('人', 1113)
('小橋流水', 466)
('門(mén)票', 456)
('江南', 456)
('景區(qū)', 454)
('水鄉(xiāng)', 416)
('江南水鄉(xiāng)', 372)
('景點(diǎn)', 358)
('人家', 337)
('景色', 287)
('沈廳', 261)
('商業(yè)', 252)
('中國(guó)', 250)
('商業(yè)化', 244)
('特色', 243)
('萬(wàn)三蹄', 215)
('風(fēng)景', 205)
('建議', 194)
('氣息', 193)
('美', 192)
('雙橋', 188)
('第一水鄉(xiāng)', 179)
('有點(diǎn)', 178)
('小鎮(zhèn)', 176)
('味道', 172)
('蘇州', 171)
('烏鎮(zhèn)', 169)
('客棧', 165)
('張廳', 161)
('導(dǎo)游', 148)
('生活', 147)
('建筑', 147)
('時(shí)間', 145)
('游玩', 143)
('沈萬(wàn)三', 142)
('文化', 140)
('夜景', 139)
('游客', 139)
產(chǎn)生的詞云圖如下:
自己的分析
??嗯零院,好不容易用自己的方法得到了可視化的結(jié)果购岗,即上述的詞云圖,那么门粪,對(duì)筆者的中秋之旅會(huì)有什么建議呢喊积?
- 周莊是個(gè)古鎮(zhèn),江南水鄉(xiāng)玄妈,小橋流水乾吻,風(fēng)景應(yīng)該很不錯(cuò)。所以拟蜻,在旅游的過(guò)程中绎签,要欣賞景色,也許夜景也是不錯(cuò)的酝锅。
- 周莊的很多景點(diǎn)及特色也在詞云圖中有展示诡必,如沈廳,張廳搔扁,雙橋爸舒,萬(wàn)三蹄等,那么稿蹲,在旅游的過(guò)程中扭勉,這些事物是不該錯(cuò)過(guò)的。
- 也有很多人對(duì)商業(yè)化提出了看法苛聘,也許涂炎,中國(guó)的古鎮(zhèn)商業(yè)化確實(shí)太嚴(yán)重了,搞得所有的古鎮(zhèn)都是一個(gè)樣子设哗,少了很多趣味唱捣。
- 至于詞云圖中為什么沒(méi)有出現(xiàn)“人”,“美”等詞語(yǔ)网梢,這是可以打一個(gè)問(wèn)號(hào)的震缭。
項(xiàng)目總結(jié)
??本次爬蟲(chóng)項(xiàng)目,爬取了攜程網(wǎng)中關(guān)于“周莊古鎮(zhèn)”的點(diǎn)評(píng)澎粟,然后對(duì)這些評(píng)論進(jìn)行中文分詞及預(yù)處理蛀序,形成一張關(guān)于“周莊古鎮(zhèn)”的詞云圖,得到筆者自己的一些分析結(jié)果活烙。當(dāng)然徐裸,我們能做的還有很多,比如對(duì)評(píng)論中提到的景區(qū)進(jìn)行統(tǒng)計(jì)啸盏,繪制景點(diǎn)提到頻數(shù)直方圖等重贺。
??所謂爬蟲(chóng),其意義在于為數(shù)據(jù)建模提供數(shù)據(jù),因此气笙,對(duì)于數(shù)據(jù)分析和建模來(lái)說(shuō)次企,爬蟲(chóng)只是萬(wàn)里長(zhǎng)征的第一步。當(dāng)然潜圃,爬蟲(chóng)也可以做很多有意義的事情缸棵,那么,你有哪些有意思的項(xiàng)目呢谭期?歡迎交流哦~
??本次爬蟲(chóng)項(xiàng)目?jī)H作為筆者的練手項(xiàng)目堵第,并不作為商用。如有轉(zhuǎn)載或商用隧出,請(qǐng)及時(shí)聯(lián)系筆者踏志,謝謝~
??提前祝大家中秋節(jié)快樂(lè)~
注意:本人現(xiàn)已開(kāi)通微信公眾號(hào): 輕松學(xué)會(huì)Python爬蟲(chóng)(微信號(hào)為:easy_web_scrape), 歡迎大家關(guān)注哦~~