摘要:前者對(duì)中文進(jìn)行分詞后者圖形化展示詞語(yǔ)的出現(xiàn)頻率。眾所周知,中文系的語(yǔ)言處理恐怕是最難的自然語(yǔ)言處理的語(yǔ)種。研究中文自然語(yǔ)言處理將是一個(gè)長(zhǎng)久而大的工程,對(duì)于分析數(shù)據(jù)我們不是要研究自然語(yǔ)言處理
接上篇,這一篇將從技術(shù)層面講講是如何實(shí)現(xiàn)的。閱讀本文您將會(huì)了解如何用python爬取微博的評(píng)論以及如何用python word_cloud庫(kù)進(jìn)行數(shù)據(jù)可視化。
上一篇:程序員代碼下的許豪杰
準(zhǔn)備工作打開微博pc m站并找到許豪杰該條微博地址:https://m.weibo.cn/status/413...
為什么要用m站地址?因?yàn)閙站可以直接抓取到api json數(shù)據(jù),而pc站雖然也有api返回的是html,相比而言選取m站會(huì)省去很多麻煩
打開該頁(yè)面,并且用chrome 的檢查工具 查看network,可以獲取到評(píng)論的api地址。
數(shù)據(jù)抓取首先觀察api返回
從返回地址上可以看到可以通過(guò)參數(shù)page 改變請(qǐng)求的頁(yè)碼,并且每頁(yè)都回返回總條數(shù)和總頁(yè)碼數(shù)。這里我決定采用多線程來(lái)抓去(其實(shí)數(shù)據(jù)量不大,也可以單線程跑)。
其中在爬取數(shù)據(jù)的時(shí)候會(huì)面臨幾個(gè)問(wèn)題:1.存儲(chǔ)選擇
我這里選用了MongoDB作為數(shù)據(jù)存儲(chǔ),因?yàn)閍pi通常返回的是json數(shù)據(jù)而json結(jié)構(gòu)和MongoDB的存儲(chǔ)方式可以結(jié)合的很默契,不需要經(jīng)過(guò)任何處理可以直接的進(jìn)行插入。
2.防爬蟲
很多網(wǎng)站可能會(huì)做一些防爬蟲的處理,面對(duì)同一個(gè)請(qǐng)求ip的短時(shí)間的高頻率請(qǐng)求會(huì)進(jìn)行服務(wù)隔斷(直接告訴你服務(wù)不可用),這個(gè)時(shí)候可以去網(wǎng)上找一些代理進(jìn)行請(qǐng)求。
3.多線程的任務(wù)分配
采用多線程爬取你當(dāng)然不能讓多個(gè)線程去爬取同樣的鏈接做別人已經(jīng)做過(guò)的事情,那樣多線程毫無(wú)意義。所以你需要制定一套規(guī)則,讓不同線程爬取不同的鏈接。
# coding=utf-8 from __future__ import division from pymongo import MongoClient import requests import sys import re import random import time import logging import threading import json from os import path import math # 爬取微博評(píng)論 # m站微博地址 weibo_url = "https://m.weibo.cn/status/4132385564040383" thread_nums = 5 #線程數(shù) #代理地址 proxies = { "http": "http://171.92.4.67:9000", "http": "http://163.125.222.240:8118", "http": "http://121.232.145.251:9000", "http": "http://121.232.147.247:9000", } # 創(chuàng)建 日志 對(duì)象 logger = logging.getLogger() handler = logging.StreamHandler() formatter = logging.Formatter( "%(asctime)s %(name)-12s %(levelname)-8s %(message)s") handler.setFormatter(formatter) logger.addHandler(handler) logger.setLevel(logging.DEBUG) mongoconn = MongoClient("127.0.0.1", 27017) mdb = mongoconn.data_analysis das_collection = mdb.weibo weiboid_reobj = re.match(r".*status/(d+)", weibo_url) weibo_id = weiboid_reobj.group(1) def scrapy_comments(weibo_id, page): weibo_comment_url = "https://m.weibo.cn/api/comments/show?id=%s&page=%d" % ( weibo_id, page) res = requests.get(weibo_comment_url) res_obj = json.loads(res.content) return res_obj def import_comments(threadName, weibo_id, page_start, page_end): logger.info("開始線程:%s" % threadName) for page in range(page_start, page_end + 1): logging.info("讀取第%s頁(yè)" % page) time.sleep(1) # continue try: res_obj = scrapy_comments(weibo_id, page) logging.info("該頁(yè)有%s條記錄" % len(res_obj["data"])) except: logging.error("讀取%s頁(yè)時(shí)發(fā)生錯(cuò)誤" % page) continue if res_obj["ok"] == 1: comments = res_obj["data"] for comment in comments: comment_text = re.sub( r"?w+[^>]*>", "", comment["text"]).encode("utf-8") if re.search(r"回復(fù)@.*:", comment_text): # 過(guò)濾掉回復(fù)別人的評(píng)論 continue comment["text"] = comment_text comment["weibo_id"] = weibo_id logging.info("讀取評(píng)論:%s" % comment["id"]) try: if das_collection.find_one({"id": comment["id"]}): logging.info("在mongodb中存在") else: logging.info("插入記錄:%s" % comment["id"]) das_collection.insert_one(comment) except: logging.error("mongodb發(fā)生錯(cuò)誤") else: logging.error("讀取第%s頁(yè)時(shí)發(fā)生錯(cuò)誤" % page) logging.info("線程%s結(jié)束" % threadName) # res_obj = scrapy_comments(weibo_id, page) if __name__ == "__main__": # 分配不同鏈接到不同的線程上去 res_obj = scrapy_comments(weibo_id, 1) if res_obj["ok"] == 1: total_number = res_obj["total_number"] logging.info("該條微博有:%s條評(píng)論" % total_number) max_page = res_obj["max"] page_nums = math.ceil(max_page / thread_nums) else: raise # print max_page # print page_nums for i in range(1, thread_nums + 1): if i < thread_nums: page_end = page_nums * i else: page_end = max_page page_start = (i - 1) * page_nums + 1 t = threading.Thread(target=import_comments, args=( i, weibo_id, int(page_start), int(page_end))) t.start()數(shù)據(jù)整理可視化(data visualization)
運(yùn)行腳本完畢,我的MongoDB得到了2萬(wàn)多條評(píng)論數(shù)據(jù),接下來(lái)要做的事是對(duì)這部分?jǐn)?shù)據(jù)進(jìn)行提取、清洗、結(jié)構(gòu)化等操作。這里順便說(shuō)明一下python 數(shù)據(jù)分析的 大致基本流程。
1.與外界進(jìn)行交互
這個(gè)過(guò)程包括數(shù)據(jù)的獲取、讀取。不管是從網(wǎng)絡(luò)資源上爬取、還是從現(xiàn)有資源(各樣的文件如文本、excel、數(shù)據(jù)庫(kù)存儲(chǔ)對(duì)象)
2.準(zhǔn)備工作
對(duì)數(shù)據(jù)進(jìn)行清洗(cleaning)、修整(munging)、整合(combining)、規(guī)范化(normalizing)、重塑(reshaping)、切片(slicing)和切塊(dicing)
3.轉(zhuǎn)換
對(duì)數(shù)據(jù)集做一些數(shù)學(xué)和統(tǒng)計(jì)運(yùn)算產(chǎn)生新的數(shù)據(jù)集
4.建模和計(jì)算
將數(shù)據(jù)跟統(tǒng)計(jì)模型、機(jī)器學(xué)習(xí)算法或其他計(jì)算工具聯(lián)系起來(lái)
5.展示
創(chuàng)建交互式的或靜態(tài)的圖片或文字摘要
下面我們來(lái)進(jìn)行2、3及5的工作:
# coding=utf-8 import sys from pymongo import MongoClient import random # 分詞庫(kù) # from snownlp import SnowNLP import jieba import uniout from collections import Counter, OrderedDict # 詞語(yǔ)云 文本統(tǒng)計(jì)可視化庫(kù) from wordcloud import WordCloud mongoconn = MongoClient("127.0.0.1", 27017) mdb = mongoconn.data_analysis das_collection = mdb.weibo total_counts = das_collection.find().count() # random_int = random.randint(0, total_counts - 1) docs = das_collection.find() print docs.count() words_counts = {} for doc in docs: print doc comment_text = doc["text"].encode("utf-8") if len(comment_text) == 0: continue words = jieba.cut(comment_text) for word in words: if word not in words_counts: words_counts[word] = 1 else: words_counts[word] += 1 for word in words_counts.keys(): if words_counts[word] < 2 or len(word) < 2: del words_counts[word] # print words_counts.items() #注意要讓中文不亂碼要指定中文字體 #fit_words 接收參數(shù)是dict eg:{"你":333,"好":23} 文字:出現(xiàn)次數(shù) wordcloud = WordCloud( font_path="/Users/cwp/font/msyh.ttf", background_color="white", width=1200, height=1000 ).fit_words(words_counts) import matplotlib.pyplot as plt plt.imshow(wordcloud, interpolation="bilinear") plt.axis("off") plt.show()
介紹下以上代碼:
我們主要用到了2個(gè)工具,jieba和word_cloud。前者對(duì)中文進(jìn)行分詞后者圖形化展示詞語(yǔ)的出現(xiàn)頻率。
眾所周知,中文系的語(yǔ)言處理恐怕是最難的自然語(yǔ)言處理(NLP)的語(yǔ)種。就基本的分詞而言都是一項(xiàng)比較困難的工作,(英語(yǔ)句子中每個(gè)單詞都是有空格分開的,而中文是由單個(gè)字組成詞連接成串組成句).
舉個(gè)例子,請(qǐng)用“孩提”造句,"那個(gè)男孩提交完代碼就下班了"。如果人工分詞,可以知道"男孩"和"提交"應(yīng)該是分開的2個(gè)詞,但是對(duì)于機(jī)器而言,要辨別"提"應(yīng)該與"男"還是"交"進(jìn)行組詞就很難辦了。要想機(jī)器能夠更精確的辨別這類問(wèn)題,就需要讓機(jī)器不停學(xué)習(xí),讓它知道這種情況該這么分而不是那么分。研究中文自然語(yǔ)言處理將是一個(gè)長(zhǎng)久而大的工程,對(duì)于分析數(shù)據(jù)(我們不是要研究自然語(yǔ)言處理
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/43415.html
摘要:從到打造一款產(chǎn)品是一種什么樣的體驗(yàn)為了回答這種知乎范的問(wèn)題,讓我來(lái)介紹下我是如何打造交易日記這款的過(guò)程。社會(huì)對(duì)群體聚集進(jìn)行生產(chǎn)產(chǎn)品的模式需求在降低。這在接下來(lái)的部分我會(huì)介紹我如何在三個(gè)月內(nèi)完成一款產(chǎn)品從到的過(guò)程。 從0到1打造一款產(chǎn)品是一種什么樣的體驗(yàn)?為了回答這種知乎范的問(wèn)題,讓我來(lái)介紹下我是如何打造交易日記這款A(yù)pp的過(guò)程。需要提前說(shuō)明的是整款iOS APP的全部工作都是我一個(gè)人完...
摘要:從到打造一款產(chǎn)品是一種什么樣的體驗(yàn)為了回答這種知乎范的問(wèn)題,讓我來(lái)介紹下我是如何打造交易日記這款的過(guò)程。社會(huì)對(duì)群體聚集進(jìn)行生產(chǎn)產(chǎn)品的模式需求在降低。這在接下來(lái)的部分我會(huì)介紹我如何在三個(gè)月內(nèi)完成一款產(chǎn)品從到的過(guò)程。 從0到1打造一款產(chǎn)品是一種什么樣的體驗(yàn)?為了回答這種知乎范的問(wèn)題,讓我來(lái)介紹下我是如何打造交易日記這款A(yù)pp的過(guò)程。需要提前說(shuō)明的是整款iOS APP的全部工作都是我一個(gè)人完...
摘要:以大量微博用戶數(shù)據(jù)為基礎(chǔ)可建立數(shù)據(jù)模型。當(dāng)前微博除了用戶自己,其他人是不能查看該用戶所有粉絲數(shù)據(jù)的。 項(xiàng)目地址:https://github.com/daweilang/... 開始抓取微博數(shù)據(jù)的時(shí)候,只是想獲得一條熱門微博下的所有評(píng)論,因?yàn)槔锩嬗胁簧賵D片廣告,所以想試試能不能分析出熱門微博評(píng)論里的異常用戶。 使用PHP的Laravel框架后,通過(guò)隊(duì)列、命令等各種功能,最后構(gòu)架了一套完...
閱讀 2118·2023-04-26 00:41
閱讀 1153·2021-09-24 10:34
閱讀 3579·2021-09-23 11:21
閱讀 4089·2021-09-22 15:06
閱讀 1563·2019-08-30 15:55
閱讀 905·2019-08-30 15:54
閱讀 1834·2019-08-30 15:48
閱讀 557·2019-08-29 13:58