標籤:

用Python爬取微博數據生成詞雲圖片

用Python爬取微博數據生成詞雲圖片

很早之前寫過一篇怎麼利用微博數據製作詞雲圖片出來,之前的寫得不完整,而且只能使用自己的數據,現在重新整理了一下,任何的微博數據都可以製作出來,放在今天應該比較應景。

一年一度的虐汪節,是繼續蹲在角落默默吃狗糧還是主動出擊告別單身汪加入散狗糧的行列就看你啦,七夕送什麼才有心意,程序猿可以試試用一種特別的方式來表達你對女神的心意。有一個創意是把她過往發的微博整理後用詞雲展示出來。本文教你怎麼用Python快速創建出有心意詞雲,即使是Python小白也能分分鐘做出來。

準備工作

本環境基於Python3,理論上Python2.7也是可行的,先安裝必要的第三方依賴包:

# requirement.txtjieba==0.38matplotlib==2.0.2numpy==1.13.1pyparsing==2.2.0requests==2.18.4scipy==0.19.1wordcloud==1.3.1

requirement.txt文件中包含上面的幾個依賴包,如果用pip方式安裝失敗,推薦使用Anaconda安裝

pip install -r requirement.txt

第一步:分析網址

打開微博移動端網址 m.weibo.cn/searchs ,找到女神的微博ID,進入她的微博主頁,分析瀏覽器發送請求的過程

打開 Chrome 瀏覽器的調試功能,選擇 Network 菜單,觀察到獲取微博數據的的介面是

m.weibo.cn/api/containe

,後面附帶了一連串的參數,這裡面有些參數是根據用戶變化的,有些是固定的,先提取出來。

uid=1192515960&luicode=10000011&lfid=100103type%3D3%26q%3D%E6%9D%8E%E5%86%B0%E5%86%B0&featurecode=20000320&type=user&containerid=1076031192515960

再來分析介面的返回結果,返回數據是一個JSON字典結構,total 是微博總條數,每一條具體的微博內容封裝在 cards 數組中,具體內容欄位是裡面的 text 欄位。很多干擾信息已隱去。

{ "cardlistInfo": { "containerid": "1076031192515960", "total": 4754, "page": 2 }, "cards": [ { "card_type": 9, "mblog": { "created_at": "08-26", "idstr": "4145069944506080", "text": "瑞士一日游圓滿結束...", } }]}

第二步:構建請求頭和查詢參數

分析完網頁後,我們開始用 requests 模擬瀏覽器構造爬蟲獲取數據,因為這裡獲取用戶的數據無需登錄微博,所以我們不需要構造

cookie信息,只需要基本的請求頭即可,具體需要哪些頭信息也可以從瀏覽器中獲取,首先構造必須要的請求參數,包括請求頭和查詢參數。

headers = { "Host": "m.weibo.cn", "Referer": "https://m.weibo.cn/u/1705822647", "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) " "Version/9.0 Mobile/13B143 Safari/601.1",}params = {"uid": "{uid}", "luicode": "20000174", "featurecode": "20000320", "type": "uid", "value": "1705822647", "containerid": "{containerid}", "page": "{page}"}

  • uid是微博用戶的id
  • containerid雖然不什麼意思,但也是和具體某個用戶相關的參數
  • page 分頁參數

第三步:構造簡單爬蟲

通過返回的數據能查詢到總微博條數 total,爬取數據直接利用 requests 提供的方法把 json 數據轉換成 Python

字典對象,從中提取出所有的 text 欄位的值並放到 blogs

列表中,提取文本之前進行簡單過濾,去掉無用信息。順便把數據寫入文件,方便下次轉換時不再重複爬取。

def fetch_data(uid=None, container_id=None): """ 抓取數據,並保存到CSV文件中 :return: """ page = 0 total = 4754 blogs = [] for i in range(0, total // 10): params[uid] = uid params[page] = str(page) params[containerid] = container_id res = requests.get(url, params=params, headers=HEADERS) cards = res.json().get("cards") for card in cards: # 每條微博的正文內容 if card.get("card_type") == 9: text = card.get("mblog").get("text") text = clean_html(text) blogs.append(text) page += 1 print("抓取第{page}頁,目前總共抓取了 {count} 條微博".format(page=page, count=len(blogs))) with codecs.open(weibo1.txt, w, encoding=utf-8) as f: f.write("
".join(blogs))

第四步:分詞處理並構建詞雲

爬蟲了所有數據之後,先進行分詞,這裡用的是結巴分詞,按照中文語境將句子進行分詞處理,分詞過程中過濾掉停止詞,處理完之後找一張參照圖,然後根據參照圖通過詞語拼裝成圖。

def generate_image(): data = [] jieba.analyse.set_stop_words("./stopwords.txt") with codecs.open("weibo1.txt", r, encoding="utf-8") as f: for text in f.readlines(): data.extend(jieba.analyse.extract_tags(text, topK=20)) data = " ".join(data) mask_img = imread(./52f90c9a5131c.jpg, flatten=True) wordcloud = WordCloud( font_path=msyh.ttc, background_color=white, mask=mask_img ).generate(data) plt.imshow(wordcloud.recolor(color_func=grey_color_func, random_state=3), interpolation="bilinear") plt.axis(off) plt.savefig(./heart2.jpg, dpi=1600)

最終效果圖:

完整代碼可以在公眾號(Python之禪)回復「qixi」獲取

關注公眾號「Python之禪」(id:vttalk)獲取最新文章

weixin.qq.com/r/7XUwKHT (二維碼自動識別)


推薦閱讀:

黃哥教Python初學者如何調試錯誤。
看完廖雪峰的python,但是感覺自己掌握不紮實,不知道該怎麼做?
Python練習第四題,批量修改圖片解析度
python爬蟲如何斷點繼續抓取?

TAG:Python |