Python網絡爬蟲-網易新聞數據分析


一、選題的背景

為什么要選擇此選題?要達到的數據分析的預期目標是什么?

  隨着社會日新月異和互聯網進入大數據時代,自媒體得到了迅猛的發展,人們獲取新聞資訊的方式越來越多,接觸和使用新聞信息的方式正在逐漸改變,受眾從被動接受信息到按需主動搜索信息,而新聞的種類繁多雜亂,各類人需要的新聞也不盡相同,為此當前以今日頭條為代表的各大媒體通過數據分析,數據挖掘等方式,在內容生產上做到精確定位用戶需求,着力打造消費痛點等特點。因此,開發一款新聞定制推送系統有助於為人們提供更為優質的新聞信息推送服務,人們完全可以根據自己的喜好定制報紙和雜志,隨着人們使用時間的增長,可以做到“機器越來越懂你”。

本次實驗目的是爬蟲網易新聞,首先利用爬蟲工具將獲取新聞數據,然后進行分析的結果可視化輸出。

 

二、主題式網絡爬蟲設計方案

1.主題式網絡爬蟲名稱

 網易新聞數據分析

2.主題式網絡爬蟲爬取的內容與數據特征分析

 爬取網易新聞界面信息,選取了國內、國際、軍事、航空、科技這五個分類進行數據分析

3.主題式網絡爬蟲設計方案概述(包括實現思路與技術難點)

  本爬蟲主要從一下幾個方面進行設計:導入需要用到的庫,獲取界面,數據分析,將數據保存至新聞數據集.csv文件里,然后根據爬取到的數據做可視化分析.

 

三、主題頁面的結構特征分析

1.主題頁面的結構與特征分析

數據來源:https://news.163.com/

 

 

 

2.Htmls 頁面解析

 

 

 

 

 

 

四、網絡爬蟲程序設計

爬蟲程序主體要包括以下各部分,要附源代碼及較詳細注釋,並在每部分程序后

面提供輸出結果的截圖。

1.數據爬取與采集

導入相關庫

 1 import requests
 2 import json
 3 import re
 4 
 5 import pandas as pd
 6 import numpy as np
 7 
 8 from sklearn.naive_bayes import MultinomialNB
 9 from sklearn.model_selection import train_test_split
10 from sklearn.metrics import accuracy_score, confusion_matrix,f1_score,classification_report
11 from sklearn.feature_extraction.text import TfidfTransformer
12 from sklearn.feature_extraction.text import TfidfVectorizer
13 
14 import jieba as jb
15 import matplotlib.pyplot as plt
16 import itertools
17 plt.rcParams['font.sans-serif']="SimHei"
18 plt.rcParams['axes.unicode_minus']=False
19 import warnings
20 warnings.filterwarnings('ignore')
21 #要爬取的新聞分類地址國內、國際、軍事、航空、科技
22 url_list={'國內':[ 'https://temp.163.com/special/00804KVA/cm_guonei.js?callback=data_callback',
23                    'https://temp.163.com/special/00804KVA/cm_guonei_0{}.js?callback=data_callback'],
24          '國際':['https://temp.163.com/special/00804KVA/cm_guoji.js?callback=data_callback',
25                  'https://temp.163.com/special/00804KVA/cm_guoji_0{}.js?callback=data_callback'],
26          '軍事':['https://temp.163.com/special/00804KVA/cm_war.js?callback=data_callback',
27                'https://temp.163.com/special/00804KVA/cm_war_0{}.js?callback=data_callback'],
28          '航空':['https://temp.163.com/special/00804KVA/cm_hangkong.js?callback=data_callback&a=2',
29                'https://temp.163.com/special/00804KVA/cm_hangkong_0{}.js?callback=data_callback&a=2'],
30          '科技':['https://tech.163.com/special/00097UHL/tech_datalist.js?callback=data_callback',
31               'https://tech.163.com/special/00097UHL/tech_datalist_0{}.js?callback=data_callback']}

爬取數據

 1 def parse_class(url):
 2     '''獲取分類下的新聞'''
 3     req=requests.get(url)
 4     text=req.text
 5     res=re.findall("title(.*?)\\n",text)
 6     #去除不規范的符號
 7     for i in range(len(res)):
 8         res[i]=re.sub("\'|\"|\:|'|,|","",res[i])
 9     return res
10 titles=[]
11 categories=[]
12 def get_result(url):
13     global titles,categories
14     temp=parse_class(url)
15     if temp[0]=='>網易-404</title>':
16         return False
17     print(url)
18     titles.extend(temp)
19     temp_class=[key for i in range(len(temp))]
20     categories.extend(temp_class)
21     return True
22 
23 for key in url_list.keys():
24     #按分類分別爬取
25     print("=========正在爬取{}新聞===========".format(key))
26     #遍歷每個分類中的子鏈接
27     #首先獲取首頁
28     get_result(url_list[key][0])
29     #循環獲取加載更多得到的頁面
30     for i in range(1,10):
31         try:
32             if get_result(url_list[key][1].format(i)):
33                 pass
34             else:
35                 continue
36         except:
37             break
38 print("爬取完畢!")

 

 

 

數據合並

 1 new=pd.DataFrame({
 2     "新聞內容":titles,
 3     "新聞類別":categories
 4 })
 5 old=pd.read_csv("新聞數據集.csv",encoding='utf-8',engine='python')
 6 def update(old,new):
 7     '''
 8     更新數據集:將本次新爬取的數據加入到數據集中(去除掉了重復元素)
 9     '''
10     data=new.append(old)
11     data=data.drop_duplicates()
12     return data
13 print("更新數據集...")
14 df=update(old,new)
15 df.to_csv("新聞數據集.csv",index=None,encoding='gbk')
16 print("更新完畢,共有數據:",df.shape[0],"")
17 df.head()  

 

2.對數據進行清洗和處理

 1 def remove_punctuation(line):
 2     line = str(line)
 3     if line.strip()=='':
 4         return ''
 5     rule = re.compile(u"[^a-zA-Z0-9\u4E00-\u9FA5]")
 6     line = rule.sub('',line)
 7     return line
 8  
 9 def stopwordslist(filepath):  
10     stopwords = [line.strip() for line in open(filepath, 'r', encoding="UTF-8").readlines()]  
11     return stopwords  
12  
13 #加載停用詞
14 stopwords = stopwordslist("./stop_words.txt")
15 #刪除除字母,數字,漢字以外的所有符號
16 df['clean_review'] = df['新聞內容'].apply(remove_punctuation)
17 #分詞,並過濾停用詞
18 
19 df['cut_review'] = df['clean_review'].apply(lambda x: " ".join([w for w in list(jb.cut(x)) if w not in stopwords]))
20 print("數據預處理完畢!")

 

 

 

4.數據分析與可視化(例如:數據柱形圖、直方圖、散點圖、盒圖、分布圖)

1 df.新聞類別.value_counts().plot(kind='bar')
2 plt.title("各個類別新聞爬取數目統計")

 

 

 

 1 # 繪制混淆矩陣函數
 2 def plot_confusion_matrix(cm, classes,
 3                           normalize=False,
 4                           title='Confusion matrix',
 5                           cmap=plt.cm.Blues):
 6     plt.figure(figsize=(8,6))
 7     plt.imshow(cm, interpolation='nearest', cmap=cmap)
 8     plt.title(title)
 9     plt.colorbar()
10     tick_marks = np.arange(len(classes))
11     plt.xticks(tick_marks, classes, rotation=45)
12     plt.yticks(tick_marks, classes)
13 
14     fmt = '.2f' if normalize else 'd'
15     thresh = cm.max() / 2.
16     for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
17         plt.text(j, i, format(cm[i, j], fmt),
18                  horizontalalignment="center",
19                  color="white" if cm[i, j] > thresh else "black")
20 
21     plt.tight_layout()
22     plt.ylabel('真實標簽')
23     plt.xlabel('預測標簽')
24     plt.show()
25 class_names=['軍事','國內','國際','科技','航空']
26 cm= confusion_matrix(y_test, y_pred)
27 title="分類准確率:{:.2f}%".format(accuracy_score(y_test,y_pred)*100)
28 plot_confusion_matrix(cm,classes=class_names,title=title)
29 print("分類評估報告如下:\n")
30 print(classification_report(y_test,y_pred))

 

 

 

5.將以上各部分的代碼匯總,附上完整程序代碼

  1 import requests
  2 import json
  3 import re
  4 
  5 import pandas as pd
  6 import numpy as np
  7 
  8 from sklearn.naive_bayes import MultinomialNB
  9 from sklearn.model_selection import train_test_split
 10 from sklearn.metrics import accuracy_score, confusion_matrix,f1_score,classification_report
 11 from sklearn.feature_extraction.text import TfidfTransformer
 12 from sklearn.feature_extraction.text import TfidfVectorizer
 13 
 14 import jieba as jb
 15 import matplotlib.pyplot as plt
 16 import itertools
 17 plt.rcParams['font.sans-serif']="SimHei"
 18 plt.rcParams['axes.unicode_minus']=False
 19 import warnings
 20 warnings.filterwarnings('ignore')
 21 #要爬取的新聞分類地址國內、國際、軍事、航空、科技
 22 url_list={'國內':[ 'https://temp.163.com/special/00804KVA/cm_guonei.js?callback=data_callback',
 23                    'https://temp.163.com/special/00804KVA/cm_guonei_0{}.js?callback=data_callback'],
 24          '國際':['https://temp.163.com/special/00804KVA/cm_guoji.js?callback=data_callback',
 25                  'https://temp.163.com/special/00804KVA/cm_guoji_0{}.js?callback=data_callback'],
 26          '軍事':['https://temp.163.com/special/00804KVA/cm_war.js?callback=data_callback',
 27                'https://temp.163.com/special/00804KVA/cm_war_0{}.js?callback=data_callback'],
 28          '航空':['https://temp.163.com/special/00804KVA/cm_hangkong.js?callback=data_callback&a=2',
 29                'https://temp.163.com/special/00804KVA/cm_hangkong_0{}.js?callback=data_callback&a=2'],
 30          '科技':['https://tech.163.com/special/00097UHL/tech_datalist.js?callback=data_callback',
 31               'https://tech.163.com/special/00097UHL/tech_datalist_0{}.js?callback=data_callback']}
 32 
 33 def parse_class(url):
 34     '''獲取分類下的新聞'''
 35     req=requests.get(url)
 36     text=req.text
 37     res=re.findall("title(.*?)\\n",text)
 38     #去除不規范的符號
 39     for i in range(len(res)):
 40         res[i]=re.sub("\'|\"|\:|'|,|","",res[i])
 41     return res
 42 titles=[]
 43 categories=[]
 44 def get_result(url):
 45     global titles,categories
 46     temp=parse_class(url)
 47     if temp[0]=='>網易-404</title>':
 48         return False
 49     print(url)
 50     titles.extend(temp)
 51     temp_class=[key for i in range(len(temp))]
 52     categories.extend(temp_class)
 53     return True
 54 
 55 for key in url_list.keys():
 56     #按分類分別爬取
 57     print("=========正在爬取{}新聞===========".format(key))
 58     #遍歷每個分類中的子鏈接
 59     #首先獲取首頁
 60     get_result(url_list[key][0])
 61     #循環獲取加載更多得到的頁面
 62     for i in range(1,10):
 63         try:
 64             if get_result(url_list[key][1].format(i)):
 65                 pass
 66             else:
 67                 continue
 68         except:
 69             break
 70 print("爬取完畢!")
 71 
 72 new=pd.DataFrame({
 73     "新聞內容":titles,
 74     "新聞類別":categories
 75 })
 76 old=pd.read_csv("新聞數據集.csv",encoding='gbk')
 77 def update(old,new):
 78     '''
 79     更新數據集:將本次新爬取的數據加入到數據集中(去除掉了重復元素)
 80     '''
 81     data=new.append(old)
 82     data=data.drop_duplicates()
 83     return data
 84 print("更新數據集...")
 85 df=update(old,new)
 86 df.to_csv("新聞數據集.csv",index=None,encoding='gbk')
 87 print("更新完畢,共有數據:",df.shape[0],"")
 88 df.head()
 89 
 90 def remove_punctuation(line):
 91     line = str(line)
 92     if line.strip()=='':
 93         return ''
 94     rule = re.compile(u"[^a-zA-Z0-9\u4E00-\u9FA5]")
 95     line = rule.sub('',line)
 96     return line
 97  
 98 def stopwordslist(filepath):  
 99     stopwords = [line.strip() for line in open(filepath, 'r', encoding="UTF-8").readlines()]  
100     return stopwords  
101  
102 #加載停用詞
103 stopwords = stopwordslist("./stop_words.txt")
104 #刪除除字母,數字,漢字以外的所有符號
105 df['clean_review'] = df['新聞內容'].apply(remove_punctuation)
106 #分詞,並過濾停用詞
107 
108 df['cut_review'] = df['clean_review'].apply(lambda x: " ".join([w for w in list(jb.cut(x)) if w not in stopwords]))
109 print("數據預處理完畢!")
110 
111 df.新聞類別.value_counts().plot(kind='bar')
112 plt.title("各個類別新聞爬取數目統計")
113 
114 # 繪制混淆矩陣函數
115 def plot_confusion_matrix(cm, classes,
116                           normalize=False,
117                           title='Confusion matrix',
118                           cmap=plt.cm.Blues):
119     plt.figure(figsize=(8,6))
120     plt.imshow(cm, interpolation='nearest', cmap=cmap)
121     plt.title(title)
122     plt.colorbar()
123     tick_marks = np.arange(len(classes))
124     plt.xticks(tick_marks, classes, rotation=45)
125     plt.yticks(tick_marks, classes)
126 
127     fmt = '.2f' if normalize else 'd'
128     thresh = cm.max() / 2.
129     for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
130         plt.text(j, i, format(cm[i, j], fmt),
131                  horizontalalignment="center",
132                  color="white" if cm[i, j] > thresh else "black")
133 
134     plt.tight_layout()
135     plt.ylabel('真實標簽')
136     plt.xlabel('預測標簽')
137     plt.show()
138 class_names=['軍事','國內','國際','科技','航空']
139 cm= confusion_matrix(y_test, y_pred)
140 title="分類准確率:{:.2f}%".format(accuracy_score(y_test,y_pred)*100)
141 plot_confusion_matrix(cm,classes=class_names,title=title)
142 print("分類評估報告如下:\n")
143 print(classification_report(y_test,y_pred))

 

五、總結

  通過這次設計讓我學會了做一個項目首先得學會進行需求分析,數據分析等。此次主題數據分析與可視化、可以看出來科技分區新聞最少。在這個設計過程中我學習到了許多知識,也對網絡爬蟲有了新的認識。但是還有不足之處,我會爭取加以改進的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM