一、选题的背景
为什么要选择此选题?要达到的数据分析的预期目标是什么?
随着社会日新月异和互联网进入大数据时代,自媒体得到了迅猛的发展,人们获取新闻资讯的方式越来越多,接触和使用新闻信息的方式正在逐渐改变,受众从被动接受信息到按需主动搜索信息,而新闻的种类繁多杂乱,各类人需要的新闻也不尽相同,为此当前以今日头条为代表的各大媒体通过数据分析,数据挖掘等方式,在内容生产上做到精确定位用户需求,着力打造消费痛点等特点。因此,开发一款新闻定制推送系统有助于为人们提供更为优质的新闻信息推送服务,人们完全可以根据自己的喜好定制报纸和杂志,随着人们使用时间的增长,可以做到“机器越来越懂你”。
本次实验目的是爬虫网易新闻,首先利用爬虫工具将获取新闻数据,然后进行分析的结果可视化输出。
二、主题式网络爬虫设计方案
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))
五、总结
通过这次设计让我学会了做一个项目首先得学会进行需求分析,数据分析等。此次主题数据分析与可视化、可以看出来科技分区新闻最少。在这个设计过程中我学习到了许多知识,也对网络爬虫有了新的认识。但是还有不足之处,我会争取加以改进的。