水木社區
任務背景:
爬取水木社區某位貼主在所有發帖版面的帖子,分析隨時間變化,貼主關註話題的變化。
主要步驟:
1.爬取帖子
這部分的實現源碼存於“水木爬蟲”文件夾中,運行環境為python3。
1)獲取發帖版面:首先是spiderman_007.py,在代碼中可設置待爬的貼主id。以貼主VChart為例,運行可得到該貼主發帖的版面及該版面的頁數,記錄在文件中“VChart.txt”中,
關鍵代碼:
1 while page_num < url[topical]: 2 content = get_url_content(now_url) 3 printView Code(now_url) 4 page_num += 1 5 page_str = str(page_num) 6 now_url = base_url + page_str 7 soup = BeautifulSoup(content, ‘html.parser‘) 8 i = 0 9 name = ‘VChart‘ 10 while i < 20: 11 new_name = soup.find_all("li")[i].next_element.next_sibling.next_element.next_element.next_element 12 13 if new_name == name: 14 f.write("\‘" + topical + "\‘" + ": " + str(url[topical]) + ", ") 15 i = 21 16 page_num = url[topical] + 1 17 elifnew_name is None: 18 i = 21 19 i += 1
部分截圖如下:
2)爬取帖子:根據Vchart.txt中的信息,運行spiderman.py可得到該貼主截至目前發布的帖子,記錄在文件“VChart_texts.txt”中。
關鍵代碼:
1 now_url = base_url + page_str 2 soup = BeautifulSoup(content, ‘html.parser‘) 3 i = 0 4 name = ‘VChart‘ 5 while i < 20: 6 if soup.find_all("li")[i]: 7 test = soup.find_all("li")[i] 8 else: 9 i += 1 10 continue 11 12 new_name = test.next_element.next_sibling.next_element.next_element.next_element 13 14 if new_name == name: 15 new_url = base_url_+soup.find_all("li")[i].next_element.next_element.get(‘href‘) 16 f.write(new_url) 17 f.write("\n") 18 # time.sleep(1) 19 20 content_ = get_url_content(new_url) 21 soup1 = BeautifulSoup(content_, ‘html.parser‘) 22 # print(soup1.prettify()) 23 s = soup1.select(".sp") 24 print(s[2].previous_sibling()[0].get_text()) 25 f.write(s[2].previous_sibling()[0].get_text()) 26 l = len(s) 27 j = 2 28 while j < l-2: 29 s1 = s[j].get_text() 30 j += 1 31 # c ut=jieba.cut(s) 32 print(s1) 33 f.write(s1) 34 time.sleep(1) 35 i += 1View Code
部分截圖如下:
2.對帖子進行排序、分詞、聚類
1)排序:對帖子按時間進行排序,運行sort_data.py可得VCharttexts_sorted.txt,
關鍵代碼:
1 def list_sort(list1): 2 pattern = re.compile("[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}") 3 4 print(list1) 5 list2 = re.findall(pattern, str(list1)) 6 list3 = list(zip(list2, list1)) 7 list3 = sorted(list3, key=lambda item: item[0]) 8 list4 = [] 9 for temp in list3: 10 list4.append(temp[1]) 11 return list4View Code
部分截圖如下:
2)分詞:將帖子按一定時間段分為不同文件,以每一年為一段為例,該貼主的帖子發帖時間為2004-2018年,共分為15個文件存於文檔->VChart->time中,運行fenci_time.py可以得到每一段時間文檔的分詞及詞頻結果,存於time文件下。
關鍵代碼:
1 def segmented(file, text): 2 ans = re.sub(‘[^\w\u4e00-\u9fff]+‘, "", text) # 正則表達式過濾出漢字 3 ans = "".join(ans.split()) 4 # seg_list = jieba.cut(ans) # 精確模式(默認是精確模式) 5 # print("[精確模式]: ", "/ ".join(seg_list)) 6 words = jieba.cut(ans, cut_all=False) 7 word_freq = {} 8 stopwords = stopwordslist(‘ting.txt‘) 9 for word in words: 10 if word in word_freq: 11 word_freq[word] += 1 12 else: 13 word_freq[word] = 1 14 15 freq_word = [] 16 for word, freq in word_freq.items(): 17 freq_word.append((word, freq)) 18 freq_word.sort(key=lambda x: x[1], reverse=True)View Code
3)分詞:運行fenlegeci.py可以得到對所有貼子進行分詞、排序並統計詞頻的文件“fencihou.txt”。
4)取出無用詞:將fencihou.txt文件中的內容復制到Excel中,需要手動刪去一些無意義和體現不出貼主發貼話題的詞,例如“中”“提到”“大作”“水木”等。
5)計算百分比:運行cout_frequency&percent.py可以根據5)、6)中得到的結果得到每個詞在每個時間段的詞頻百分比,生成文件“統計.xls”。詞頻百分比=該詞的詞頻÷該時間段所有詞的詞頻總數×100%。
關鍵代碼:
1 readbook = xlrd.open_workbook(r‘統計_all.xlsx‘) 2 sheet = readbook.sheet_by_name(‘Sheet1‘) 3 nrows = sheet.nrows 4 f = xlwt.Workbook(encoding=‘utf-8‘) 5 table = f.add_sheet(‘data‘) 6 7 table.write(i, j, 0) 8 f.save("統計.xls")View Code
部分截圖如下:
6)生成.csv文件:在A1處填上“word”,將文件另存為“VChart時間詞頻百分比.csv”,即存為.csv格式的文件,註意編碼方式要選擇“UTF-8”。該文件可以被用於在weka軟件中進行聚類。
7)聚類:打開weka->Explorer->Open file,選則打開6)中的csv文件。
選則Cluster,點擊Choose選則SimpleKmeans算法進行聚類。
點擊下圖紅框處可以設置KMeans相關參數。選則“Classes to clusters evaluation”並按“word”聚類,點擊“Start”即可運行。
運行結束後,左下角會有運行記錄,右鍵選則Save result buffer可以得到結果文件。
為了方便查看內容,推薦使用Notepad++打開文件。
8)獲取聚類結果:weka的運行結果文件中有很多用不到的信息,運行clustering文件夾下的get_class_words.py文件可以得到每一類的詞的信息,形式如下:
3.展示
對每一類詞隨時間變化的展示,主要參考了https://github.com/TangliziGit/ColumnsAnimation.git中的項目。
1)統計每一類詞的詞頻百分比在各個時間段內的平均值,用於展示。
2)使用ColumnsAnimation->data中的getdata.py可以得到自己的展示數據的data.json文件。
3)在data.json文件開頭添加“var TotalData=”並另存為“data.js”放在ColumnsAnimation目錄下,打開animation.html即可看到展示效果。
項目中的11-24.mp4為效果錄屏文件。
本項目地址:https://git.coding.net/Ruidxr/ShuiMu.git
水木社區