1. 程式人生 > >水木社群

水木社群

任務背景:

爬取水木社群某位貼主在所有發帖版面的帖子,分析隨時間變化,貼主關注話題的變化。

主要步驟:

1.爬取帖子

這部分的實現原始碼存於“水木爬蟲”資料夾中,執行環境為python3。

1)獲取發帖版面:首先是spiderman_007.py,在程式碼中可設定待爬的貼主id。以貼主VChart為例,執行可得到該貼主發帖的版面及該版面的頁數,記錄在檔案中“VChart.txt”中,

關鍵程式碼:

 1         while page_num < url[topical]:
 2             content = get_url_content(now_url)
3 print(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 elif
new_name is None: 18 i = 21 19 i += 1
View Code

部分截圖如下:

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 += 1
View 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 list4
View 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