用掘金半年多了,但是從來都沒有寫過文章,最近剛好有時間加上手癢癢所有就有了這第一篇掘金文章。
剛好最近在開十九大,2018政府工作報告全文出來了,在鳳凰網能細細研讀。作為一個程式設計師,怎麼能忍受看那麼多中文呢!所以果斷來搞事啊!思路大概就是:使用最近剛釋出的for humans的requests_html庫獲取到報告全文,然後使用jieba來進行分詞把分好的詞就可以用wordcloud來做詞雲了。
1. 獲取資料
百度關鍵字 2018政府工作報告 可以發現有很多,連結我就打出來了news.ifeng.com/a/20180305/… 那我們就來看看網頁結構吧!
劃出重點了(懶人可以對著那一堆中文右鍵copy→copy xpath 一鍵獲取xpath路徑),獲取到路徑之後我們就可以愉快的使用chrome的xpath外掛來檢視路徑對不對了(當然如果你想用beautifulsoup的話就是div#main_content p
,個人不推薦用beautifulsoup,畢竟解析速度擺在那了)。
但是我們也需要注意,最後一個不是報告的內容,等會在程式碼裡面處理就好了。
好了,獲取到了我們就開始開心的寫程式碼吧!
session= HTMLSession()
response= session.get(url)
report_text= response.html.xpath('//*[@id="main_content"]/p/text()')[:-1] if response.htmlis not None else 'NULL'
print(report_text)
複製程式碼
上面這個圖片就是返回的list,然後我們遍歷一下取出全部資料後拼接返回給jieba分詞。
def get_info(url):
report= ''
session= HTMLSession()
response= session.get(url)
report_text= response.html.xpath('//*[@id="main_content"]/p/text()')[:-1] if response.htmlis not None else 'NULL'
print(report_text)
for iin report_text:
report+= i
return report
複製程式碼
2. jieba分詞
分詞其實很簡單,只需要下面這一行程式碼就可以實現了。
words= [wordfor wordin jieba.cut(report,cut_all=True) if len(word) >= 2]
cut方法引數:(分詞的字串,cut_all是否開啟全模式),全模式的意思就是會把一個詞前後斷句,比如:大傻逼,會分詞成:大傻,傻逼和大傻逼 另外這裡還做了下判斷,長度大於等於2才算一個詞。執行下把分詞後list遍歷下。
到了這裡我突然想看一下高頻詞到底有哪些,所以用了一下collections的Count來計算一下
c = Counter(words)
for word_freq in c.most_common(10):
word, freq = word_freq
print(word, freq)
複製程式碼
選出頻率前10的詞,於是得到了下面圖片的資料
3.生成詞雲
python生成詞雲當然是用wordcloud,wordcloud是基於matplotlib的專門生成詞雲的庫。
用這個庫最關鍵的就是WordCloud建構函式:
引數詳解:
font_path:字型路徑,就是繪製詞雲用的字型,比如monaco.ttf
width:輸出的畫布寬度,預設400畫素
height:輸出的畫布寬度,預設200畫素
margin:畫布偏移,預設2畫素
prefer_horizontal: 詞語水平方向排版出現的頻率,預設0.9,垂直方向出現概率0.1
mask:如果引數為空,則使用二維遮罩繪製詞雲。如果 mask 非空,設定的寬高值將被忽略,遮罩形狀被 mask,除全白(#FFFFFF)的部分將不會繪製,其餘部分會用於繪製詞雲。如:bg_pic = imread('讀取一張圖片.png'),背景圖片的畫布一定要設定為白色(#FFFFFF),然後顯示的形狀為不是白色的其他顏色。可以用ps工具將自己要顯示的形狀複製到一個純白色的畫布上再儲存,就ok了。
scale:按照比例進行放大畫布,如設定為1.5,則長和寬都是原來畫布的1.5倍
color_func:生成新顏色的函式,如果為空,則使用 self.color_func
max_words:顯示的詞的最大個數
min_font_size:顯示的最小字型大小
stopwords:需要遮蔽的詞(字串集合),為空使用內建STOPWORDS
random_state:如果給出了一個隨機物件,用作生成一個隨機數
background_color:背景顏色,預設為黑色
max_font_size:顯示的最大的字型大小
font_step:字型步長,如果步長大於1,會加快運算但是可能導致結果出現較大的誤差
mode:當引數為"RGBA",並且background_color不為空時,背景為透明。預設RGB
relative_scaling:詞頻和字型大小的關聯性,預設5
regexp:使用正規表示式分隔輸入的文字
collocations:是否包括兩個詞的搭配
colormap:給每個單詞隨機分配顏色,若指定color_func,則忽略該方法
normalize_plurals:是否刪除尾隨的詞語
常用的幾個方法:
fit_words(frequencies) //根據詞頻生成詞雲
generate(text) //根據文字生成詞雲
generate_from_frequencies(frequencies[, ...]) #根據詞頻生成詞雲
generate_from_text(text) #根據文字生成詞雲
process_text(text) #將長文字分詞並去除遮蔽詞(此處指英語,中文分詞還是需要自己用別的庫先行實現,使用上面的 fit_words(frequencies) )
recolor([random_state, color_func, colormap]) # 對現有輸出重新著色。重新上色會比重新生成整個詞雲快很多。
to_array() #轉化為 numpy array
to_file(filename) #輸出到檔案
看到這裡是不是懵了?反正我是看懵了,算了,直接寫吧!
在這裡我遇到了中文生成詞雲只出現框框沒有字的bug!!!
path = r'simfang.tff'
查了一下路徑要寫成這樣要不然會出現OSError: cannot open resource
的問題。
所以就有了下面的的程式碼
def word_cloud(word):
path= r'C:\Windows\Fonts\simfang.ttf' # 字型路徑
bg_pic= imread(r'D:\blog\20160303160528046.png') # 讀取模板圖片
image_colors= ImageColorGenerator(bg_pic) # 從模板圖片生成顏色值
wc= WordCloud(font_path=path,
background_color="white",
mask=bg_pic,
stopwords=STOPWORDS.add("said"),
max_font_size=500,
color_func=image_colors,
scale=1.5)
wc= wc.generate(word)
wc.to_file(r'D:\blog\result.jpg')
複製程式碼
根據官方的照片例子的出來的詞雲是這樣的:
但是既然是政府工作報告,那肯定要上我的偶像,全世界最大公司的老總
哈哈,詞雲就這樣生成了!總結
詞雲還是很好玩的,很簡單,對看資料很直觀。話說今天把爬蟲和資料分析小小結合起來,雖然都是皮毛,但是我們還是有未來的(是的,我偶像是這麼說的)!今天跟一個朋友聊天,聊到了平常都在爬什麼資料,然後他說你連視訊都沒爬過,被深深的鄙視了一番,估計這個星期會把爬視訊這個技能學會,哈哈,下一篇文章就是爬視訊的文章了(就決定是你了)!
照例在最後附一下全部的程式碼:
# -*- coding:utf-8 -*-
# 作者:Jason
import jieba
from requests_htmlimport HTMLSession
from collectionsimport Counter
from wordcloudimport WordCloud, STOPWORDS, ImageColorGenerator
from scipy.miscimport imread
target_url= 'http://news.ifeng.com/a/20180305/56472392_0.shtml'
def get_info(url):
report= ''
session= HTMLSession()
response= session.get(url)
report_text= response.html.xpath('//*[@id="main_content"]/p/text()')[:-1] if response.htmlis not None else 'NULL'
print(report_text)
for i in report_text:
report+= i
return report
def handle_word(report):
words= [wordfor wordin jieba.cut(report,cut_all=True) if len(word) >= 2]
# c = Counter(words)
# for word_freq in c.most_common(10):
# word, freq = word_freq
# print(word, freq)
return words
def word_cloud(word):
path= r'C:\Windows\Fonts\simfang.ttf' # 字型路徑
bg_pic= imread(r'D:\blog\20160303160528046.png') # 讀取模板圖片
image_colors= ImageColorGenerator(bg_pic) # 從模板圖片生成顏色值
wc= WordCloud(font_path=path,
background_color="white",
mask=bg_pic,
stopwords=STOPWORDS.add("said"),
max_font_size=500,
color_func=image_colors,
scale=1.5)
wc= wc.generate(word)
wc.to_file(r'D:\blog\result.jpg')
if __name__== '__main__':
words= handle_word(get_info(target_url))
data= r" ".join(words)
word_cloud(data)
複製程式碼