爬取新浪新闻国际新闻分享数的排名
(一)、选题的背景
新浪新闻是新浪集团旗下的智能信息平台,致力于利用大数据和人工智能技术,为用户提供更丰富、场景化和个性化的内容阅读体验。新浪新闻与微博打通了双平台的内容、数据和账号体系,为用户提供全网资讯、热点要闻、深度精选、精彩视频、高清图集等精彩内容。
截至2021年8月,数据显示,新浪新闻MAU达到1.46亿,DAU突破8300万,实现连续22个季度的高速增长,稳居行业前三。
(二)、主题式网络爬虫设计方案(10 分)
1.主题式网络爬虫名称
爬取新浪新闻国际新闻分享数排名
2.主题式网络爬虫爬取的内容与数据特征分析
对国际新闻分享数排行榜进行爬取“排名”,“标题”,“分享数”
3.主题式网络爬虫设计方案概述(包括实现思路与技术难点)
(三)、主题页面的结构特征分析(10 分)
<a>中找到标题,<td>中可以找到排名以及分享数
url为http://news.sina.com.cn/hotnews/index_weekly.shtml

2.Htmls 页面解析


3.节点(标签)查找方法与遍历方

(必要时画出节点树结构)
(四)、网络爬虫程序设计(60 分)
爬虫程序主体要包括以下各部分,要附源代码及较详细注释,并在每部分程序后
面提供输出结果的截图。
1.数据爬取与采集
1 #导入相关库
2 import requests
3 #引入pandas用于数据可视化
4 import pandas as pd
5 import numpy as np
6 import matplotlib.pyplot as plt
7 import matplotlib
8 import csv
9 import scipy as sp
10 import seaborn as sns
11 from sklearn.linear_model import LinearRegression
12 from bs4 import BeautifulSoup
13 from pandas import DataFrame
14 from scipy.optimize import leastsq
15 #搜索网址
16 url='http://news.sina.com.cn/hotnews/index_weekly.shtml'
17 #伪装爬虫
18 headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 Edg/96.0.1054.62'}
19 r = requests.get(url, headers=headers,timeout=10)
20
21 def getHTMLText(url,timeout = 30):
22 try:
23 #用requests抓取网页信息
24 r = requests.get(url, timeout = 30)
25 #可以让程序产生异常时停止程序
26 r.raise_for_status()
27 #设置编码标准
28 r.encoding = r.apparent_encoding
29 return r.text
30 except:
31 return '产生异常'
32
33
34 #统一编码
35 html=r.text
36 #html.parser表示用BeautifulSoup库解析网页
37 soup=BeautifulSoup(html,'html.parser')
38 #基于bs4库HTML的格式输出,让页面更友好的显示
39 print(soup.prettify())

1 #爬取数据
2 #爬取排行
3 c=[]
4 for i in soup.find_all('td',class_='')[698:717:3]:
5 c.append(i.get_text().strip())
6
7 print(c)
8
9 #爬取分享数
10
11 a=[]
12 for i in soup.find_all('td',class_='')[698:717:3]:
13 a.append(i.get_text().strip())
14
15 print(a)
16
17 #爬取标题名
18 b=[]
19 for i in soup.find_all('a',class_='')[344:352]:
20 b.append(i.get_text().strip())
21
22 print(b)
1 #将数据整理成表格
2 import pandas as pd
3 num=7
4
5 print('{:^5}\t{:^40}\t{:^20}'.format('排名', '标题', '分享数'))
6
7 lst=[]
8 for i in range(num):
9 print('{:^5}\t{:^40}\t{:^20}'.format(i+1, b[i], a[i]))
10 lst.append([i+1,b[i],a[i]])
11
12 df = pd.DataFrame(lst,columns=['排名','标题','分享数'])
13
14 #将表格存入excel表中
15 rank = r'rank.xlsx'
16 df.to_excel(rank)

2.对数据进行清洗和处理
1 #读取excel表
2 df=pd.DataFrame(pd.read_excel('rank.xlsx'))
3 print(df)

1 #数据清洗 2 3 #重复值确认 4 print(df.duplicated()) 5 6 #统计空值 7 print(df.isnull().sum()) #返回0则没有空值 8 9 #缺失值处理 10 print(df[df.isnull().values==True]) #返回无缺失值 11 12 #用describe()命令显示描述性统计指标 13 print(df.describe())

3.文本分析(可选):jieba 分词、wordcloud 的分词可视化
4.数据分析与可视化(例如:数据柱形图、直方图、散点图、盒图、分布图)
1 #绘制折线图
2 import numpy as np
3 import pandas as pd
4 import matplotlib.pyplot as plt
5 plt.rcParams['font.sans-serif'] = ['SimHei']
6 # 用来正常显示中文标签
7 plt.rcParams['axes.unicode_minus'] = False
8 # 用来正常显示负号
9 plt.plot(df['排名'],df['分享数'],'r')
10 plt.scatter(df['排名'],df['分享数'],color="green",label='分享数')
11 plt.ylabel('分享数')
12 plt.xlabel('排名')
13 plt.title('排名与分享数的关系')
14 plt.grid()
15 plt.legend(loc=2)
16 plt.show()

1 #绘制折线图 2 import numpy as np 3 import pandas as pd 4 import matplotlib.pyplot as plt 5 x=df['排名'] 6 y=df['分享数'] 7 plt.figure(figsize=[10,4]) 8 9 plt.subplot(2,1,1) 10 plt.plot(x,y,color='blue', marker='o') 11 plt.plot(x,y , color='black') 12 plt.axis((0, 8, 0,700)) 13 plt.grid() 14 15 plt.subplot(2,1,2) 16 plt.plot(x,y,'r--') 17 plt.axis((0, 8, 0,700)) 18 plt.grid() 19 plt.show()

5.根据数据之间的关系,分析两个变量之间的相关系数,画出散点图,并建立变
量之间的回归方程(一元或多元)。
1 #构建数据分析模型
2
3 import numpy as np
4 import pandas as pd
5 import sklearn
6 from sklearn import datasets
7 from sklearn.linear_model import LinearRegression
8 X = df[["排名"]]
9 predict_model = LinearRegression()
10 predict_model.fit(X, df[['分享数']])
11
12 print("回归系数为{}".format(predict_model.coef_))
13 print("回归方程截距:{}".format(predict_model.intercept_))

1 #选择排名和热度两个特征变量,绘制分布图,用最小二乘法分析两个变量间的二次拟合方程和拟合曲线
2 colnames=[" ","排名","分享数"]
3 df=pd.DataFrame(pd.read_excel('rank.xlsx'))
4 X = df.排名
5 Y = df.分享数
6 def A():
7 plt.scatter(X,Y,color="blue",linewidth=2)
8 plt.title("分析图",color="blue")
9 plt.grid()
10 plt.show()
11 def B():
12 plt.scatter(X,Y,color="green",linewidth=2)
13 plt.title("分析图",color="blue")
14 plt.grid()
15 plt.show()
16 def func(p,x):
17 a,b,c=p
18 return a*x*x+b*x+c
19 def error(p,x,y):
20 return func(p,x)-y
21 def main():
22 plt.figure(figsize=(10,6))
23 p0=[0,0,0]
24 Para = leastsq(error,p0,args=(X,Y))
25 a,b,c=Para[0]
26 print("a=",a,"b=",b,"c=",c)
27 plt.scatter(X,Y,color="blue",linewidth=2)
28 x=np.linspace(0,20,20)
29 y=a*x*x+b*x+c
30 plt.plot(x,y,color="blue",linewidth=2,)
31 plt.title("分析图")
32 plt.grid()
33 plt.show()
34 print(A())
35 print(B())
36 print(main())


6.数据持久化
1 #数据持久化 2 3 rank = r'rank.xlsx' 4 df.to_excel(rank)

7.将以上各部分的代码汇总,附上完整程序代码
1 #导入相关库
2 import requests
3 #引入pandas用于数据可视化
4 import pandas as pd
5 import numpy as np
6 import matplotlib.pyplot as plt
7 import matplotlib
8 import csv
9 import scipy as sp
10 import seaborn as sns
11 from sklearn.linear_model import LinearRegression
12 from bs4 import BeautifulSoup
13 from pandas import DataFrame
14 from scipy.optimize import leastsq
15 #搜索网址
16 url='http://news.sina.com.cn/hotnews/index_weekly.shtml'
17 #伪装爬虫
18 headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 Edg/96.0.1054.62'}
19 r = requests.get(url, headers=headers,timeout=10)
20
21 def getHTMLText(url,timeout = 30):
22 try:
23
24 #用requests抓取网页信息
25 r = requests.get(url, timeout = 30)
26 #可以让程序产生异常时停止程序
27 r.raise_for_status()
28 #设置编码标准
29
30 r.encoding = r.apparent_encoding
31 return r.text
32
33 except:
34
35 return '产生异常'
36
37
38 #统一编码
39
40 html=r.text
41 #html.parser表示用BeautifulSoup库解析网页
42 soup=BeautifulSoup(html,'html.parser')
43 #基于bs4库HTML的格式输出,让页面更友好的显示
44 print(soup.prettify())
45
46
47 #爬取数据
48
49 #爬取排行
50 c=[]
51 for i in soup.find_all('td',class_='')[698:717:3]:
52 c.append(i.get_text().strip())
53
54 print(c)
55
56 #爬取分享数
57
58 a=[]
59 for i in soup.find_all('td',class_='')[698:717:3]:
60 a.append(i.get_text().strip())
61
62 print(a)
63
64 #爬取标题名
65
66 b=[]
67 for i in soup.find_all('a',class_='')[344:352]:
68 b.append(i.get_text().strip())
69
70 print(b)
71
72 #将数据整理成表格
73
74 import pandas as pd
75 num=7
76
77 print('{:^5}\t{:^40}\t{:^20}'.format('排名', '标题', '分享数'))
78
79 lst=[]
80 for i in range(num):
81 print('{:^5}\t{:^40}\t{:^20}'.format(i+1, b[i], a[i]))
82 lst.append([i+1,b[i],a[i]])
83
84 df = pd.DataFrame(lst,columns=['排名','标题','分享数'])
85
86 #将表格存入excel表中
87
88 rank = r'rank.xlsx'
89 df.to_excel(rank)
90
91 #读取excel表
92
93 df=pd.DataFrame(pd.read_excel('rank.xlsx'))
94 print(df)
95
96 #数据清洗
97
98 #重复值确认
99
100 print(df.duplicated())
101
102 #统计空值
103
104 print(df.isnull().sum()) #返回0则没有空值
105
106 ##缺失值处理
107
108 print(df[df.isnull().values==True]) #返回无缺失值
109
110 ##用describe()命令显示描述性统计指标
111 print(df.describe())
112
113 #绘制折线图
114
115 import numpy as np
116 import pandas as pd
117 import matplotlib.pyplot as plt
118 plt.rcParams['font.sans-serif'] = ['SimHei']
119
120 # 用来正常显示中文标签
121
122 plt.rcParams['axes.unicode_minus'] = False
123
124 # 用来正常显示负号
125
126 plt.plot(df['排名'],df['分享数'],'r')
127 plt.scatter(df['排名'],df['分享数'],color="green",label='分享数')
128 plt.ylabel('分享数')
129 plt.xlabel('排名')
130 plt.title('排名与分享数的关系')
131 plt.grid()
132 plt.legend(loc=2)
133 plt.show()
134
135 #绘制折线图
136
137 import numpy as np
138 import pandas as pd
139 import matplotlib.pyplot as plt
140 x=df['排名']
141 y=df['分享数']
142 plt.figure(figsize=[10,4])
143
144 plt.subplot(2,1,1)
145 plt.plot(x,y,color='blue', marker='o')
146 plt.plot(x,y , color='black')
147 plt.axis((0, 8, 0,700))
148 plt.grid()
149
150 plt.subplot(2,1,2)
151 plt.plot(x,y,'r--')
152 plt.axis((0, 8, 0,700))
153 plt.grid()
154 plt.show()
155
156 #构建数据分析模型
157
158 import numpy as np
159 import pandas as pd
160 import sklearn
161 from sklearn import datasets
162 from sklearn.linear_model import LinearRegression
163 X = df[["排名"]]
164 predict_model = LinearRegression()
165 predict_model.fit(X, df[['分享数']])
166
167 print("回归系数为{}".format(predict_model.coef_))
168 print("回归方程截距:{}".format(predict_model.intercept_))
169
170 #选择排名和热度两个特征变量,绘制分布图,用最小二乘法分析两个变量间的二次拟合方程和拟合曲线
171 colnames=[" ","排名","分享数"]
172 df=pd.DataFrame(pd.read_excel('rank.xlsx'))
173 X = df.排名
174 Y = df.分享数
175 def A():
176 plt.scatter(X,Y,color="blue",linewidth=2)
177 plt.title("分析图",color="blue")
178 plt.grid()
179 plt.show()
180 def B():
181 plt.scatter(X,Y,color="green",linewidth=2)
182 plt.title("分析图",color="blue")
183 plt.grid()
184 plt.show()
185 def func(p,x):
186 a,b,c=p
187 return a*x*x+b*x+c
188 def error(p,x,y):
189 return func(p,x)-y
190 def main():
191 plt.figure(figsize=(10,6))
192 p0=[0,0,0]
193 Para = leastsq(error,p0,args=(X,Y))
194 a,b,c=Para[0]
195 print("a=",a,"b=",b,"c=",c)
196 plt.scatter(X,Y,color="blue",linewidth=2)
197 x=np.linspace(0,20,20)
198 y=a*x*x+b*x+c
199 plt.plot(x,y,color="blue",linewidth=2,)
200 plt.title("分析图")
201 plt.grid()
202 plt.show()
203 print(A())
204 print(B())
205 print(main())
206
207 #数据持久化
208
209 rank = r'rank.xlsx'
210 df.to_excel(rank)
(五)、总结(10 分)
1.经过对主题数据的分析与可视化,可以得到哪些结论?是否达到预期的目标?
通过对数据的分析,我们可以得到新浪新闻网在国际新闻的关注上差别会很大,然而并没有达到预期目标,并不知道为什么会有如此大的差异。
2.在完成此设计过程中,得到哪些收获?以及要改进的建议?
在完成此次设计的途中可谓是九九八十一难,无论是网站爬取,图表制作还是数据分析,都出现过大大小小的问题。例如在寻找要爬取的网站时,曾因为无法找到相关信息,出现乱码等,不得不反反复复更换十来个网站进行爬取。在设计过程中,我收获到了如何编写爬虫程序,如何把网页想要爬取的内容提取出来,怎么画出自己想要的图像。改进的地方可能是编写代码经验不足吧,写代码的时候比较吃力。

浙公网安备 33010602011771号