Python网络爬虫-网易新闻数据分析

一、选题的背景

为什么要选择此选题?要达到的数据分析的预期目标是什么?

  随着社会日新月异和互联网进入大数据时代,自媒体得到了迅猛的发展,人们获取新闻资讯的方式越来越多,接触和使用新闻信息的方式正在逐渐改变,受众从被动接受信息到按需主动搜索信息,而新闻的种类繁多杂乱,各类人需要的新闻也不尽相同,为此当前以今日头条为代表的各大媒体通过数据分析,数据挖掘等方式,在内容生产上做到精确定位用户需求,着力打造消费痛点等特点。因此,开发一款新闻定制推送系统有助于为人们提供更为优质的新闻信息推送服务,人们完全可以根据自己的喜好定制报纸和杂志,随着人们使用时间的增长,可以做到“机器越来越懂你”。

本次实验目的是爬虫网易新闻,首先利用爬虫工具将获取新闻数据,然后进行分析的结果可视化输出。

 

二、主题式网络爬虫设计方案

1.主题式网络爬虫名称

 网易新闻数据分析

2.主题式网络爬虫爬取的内容与数据特征分析

 爬取网易新闻界面信息,选取了国内、国际、军事、航空、科技这五个分类进行数据分析

3.主题式网络爬虫设计方案概述(包括实现思路与技术难点)

  本爬虫主要从一下几个方面进行设计:导入需要用到的库,获取界面,数据分析,将数据保存至新闻数据集.csv文件里,然后根据爬取到的数据做可视化分析.

 

三、主题页面的结构特征分析

1.主题页面的结构与特征分析

数据来源:https://news.163.com/

Python网络爬虫-网易新闻数据分析

 

 

 

2.Htmls 页面解析

 

 

 Python网络爬虫-网易新闻数据分析

 

 

 

四、网络爬虫程序设计

爬虫程序主体要包括以下各部分,要附源代码及较详细注释,并在每部分程序后

面提供输出结果的截图。

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("爬取完毕!")

Python网络爬虫-网易新闻数据分析

 

 

 

数据合并

 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("数据预处理完毕!")

Python网络爬虫-网易新闻数据分析

 

 

 

4.数据分析与可视化(例如:数据柱形图、直方图、散点图、盒图、分布图)

1 df.新闻类别.value_counts().plot(kind='bar')
2 plt.title("各个类别新闻爬取数目统计")

Python网络爬虫-网易新闻数据分析

 

 

 

 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))

Python网络爬虫-网易新闻数据分析

 

 

 

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))

 

五、总结

  通过这次设计让我学会了做一个项目首先得学会进行需求分析,数据分析等。此次主题数据分析与可视化、可以看出来科技分区新闻最少。在这个设计过程中我学习到了许多知识,也对网络爬虫有了新的认识。但是还有不足之处,我会争取加以改进的。

上一篇:k8s常用命令


下一篇:Android系统四大组件工作过程分析(一)- Service