python的requests_html庫和詞雲分析2018政府工做報告全文

用掘金半年多了,可是歷來都沒有寫過文章,最近恰好有時間加上手癢癢全部就有了這第一篇掘金文章。html

恰好最近在開十九大,2018政府工做報告全文出來了,在鳳凰網能細細研讀。做爲一個程序員,怎麼能忍受看那麼多中文呢!因此果斷來搞事啊!

思路大概就是:使用最近剛發佈的for humans的requests_html庫獲取到報告全文,而後使用jieba來進行分詞把分好的詞就能夠用wordcloud來作詞雲了。python

1. 獲取數據

百度關鍵字 2018政府工做報告 能夠發現有不少,連接我就打出來了news.ifeng.com/a/20180305/… 那咱們就來看看網頁結構吧!程序員

網頁的html結構
劃出重點了(懶人能夠對着那一堆中文右鍵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分詞

分詞其實很簡單,只須要下面這一行代碼就能夠實現了。chrome

words= [wordfor wordin jieba.cut(report,cut_all=True) if len(word) >= 2]bash

cut方法參數:(分詞的字符串,cut_all是否打開全模式),全模式的意思就是會把一個詞先後斷句,好比:大傻逼,會分詞成:大傻,傻逼和大傻逼 另外這裏還作了下判斷,長度大於等於2纔算一個詞。運行下把分詞後list遍歷下。session

到了這裏我忽然想看一下高頻詞到底有哪些,因此用了一下collections的Count來計算一下dom

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)
複製代碼
相關文章
相關標籤/搜索