1.分析网页
本次爬取的是最好大学网软科中国最好大学排名2019:http://www.zuihaodaxue.cn/zuihaodaxuepaiming2019.html
2.爬取可行性分析:
理论上,每个网站都会有网络爬虫排除出标准文件robots.txt,这一文件内说明了网站是否可以进行爬取以及可以爬取什么内容。一般网站的robots.txt放置在根目录下,所以可以直接访问进行查看,访问http://www.zuihaodaxue.com/robots.txt,结果显示404未找到文件,说明此网站是可以爬取的
3.分析需要的数据
本次爬取所需数据为表格中的排名、学校名称、省市、总分等数据。
经过网页源代码分析发现我所需要的数据都存于<tbody/>标签下的子标签中
而我所需要的排名、学校名称、省市、总分等数据都存放于<tbody/>标签下的<tr></tr>标签下的标签<td> </td>中,因此爬取的数据要提取td标签的内容
四、代码分析
实现步骤:
- 获取指定网页内容
- 筛选需要的内容
- 存入csv文件
- 统计各个地区大学数量
爬取存入csv源代码:
# 编写程序代码如下:
import csv
import bs4
from urllib import request
from bs4 import BeautifulSoup
'''(1)获取网站页面'''
def getHTMLText(url):
try:
resp = request.urlopen(url)
html_data = resp.read().decode('utf-8')
return html_data
except:
return ""
'''(2)处理页面,提取相关信息'''
def fillUnivList(ulist, html):
soup = BeautifulSoup(html, "html.parser")
for tr in soup.find('tbody').children: # 搜索'tbody'后面的子节点
if isinstance(tr, bs4.element.Tag):
tds = tr('td')
ulist.append([tds[0].string, tds[1].string, tds[2].string,tds[3].string])
'''(3)解析数据,格式化输出结果'''
def write(ulist,num):
with open('save1.csv', 'a', newline='', encoding='utf-8') as data_csv:
for i in range(num):
u=ulist[i]
# dialect为打开csv文件的方式,默认是excel,delimiter="\t"参数指写入的时候的分隔符
try:
csv_writer = csv.writer(data_csv)
csv_writer.writerow([u[0],u[1],u[2],u[3]])
except Exception as e:
print(e)
if __name__ == '__main__':
uinfo = []
url = 'http://www.zuihaodaxue.cn/zuihaodaxuepaiming2019.html'
html = getHTMLText(url)
fillUnivList(uinfo, html)
write(uinfo, 100)
数据可视化分析代码:
import csv
import matplotlib.pyplot as plt
import pandas as pd
import pylab as pl
# 指定默认字体
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['font.family'] = 'sans-serif'
# 解决符号'-'乱码问题
plt.rcParams['axes.unicode_minus'] = False
# 默认非常难看,设置主题
plt.style.use('ggplot')
# 设置柱形图大小
fig = plt.figure(figsize=(8,5))
colors1 = "#6D6D6D"
# 1.先导入原始数据
cloumns = ['num','name','area','score']
# 打开csv文件
df = pd.read_csv('save1.csv',encoding="utf-8",header=None,names=cloumns,index_col='num')
def annlysis1():
df_score = df.sort_values('score', ascending=False)
name1 = df_score.name[:10] # x轴坐标
score1 = df_score.score[:10] # y轴坐标
plt.bar(range(10), score1, tick_label=name1) # 绘制条形图,用range()能保持x轴顺序一致
plt.ylim(50, 100)
plt.title("大学总分最高Top10", color=colors1)
plt.xlabel("大学名称")
plt.ylabel("总分")
# 标记数值
for x, y in enumerate(list(score1)):
plt.text(x, y + 0.01, '%s' % round(y, 1), ha='center', color=colors1)
pass
pl.xticks(rotation=270) # 旋转270°
plt.tight_layout() # 去除空白
plt.show()
pass
#地区数量排名
def annlysis2():
country = list()
with open('save1.csv', 'r', encoding="utf-8") as file:
reader = csv.reader(file)
adress = [row[2] for row in reader]
adress1 = {}
for i in adress:
adress1[i] = adress.count(i) # 字典
print(adress1)
adress2 = tuple(adress1) # key
count = tuple(adress1.values()) # value
plt.figure(figsize=(10, 8), dpi=80)
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 再创建一个规格为 1 x 1 的子图
plt.subplot(1, 1, 1)
# 柱子总数
N = len(adress2)
# 包含每个柱子对应值
values = count
# 包含每个柱子下标的序列 等分横轴
index = pl.np.arange(N)
# 柱子的宽度
width = 0.65
p2 = plt.bar(index, values, width, label="数量", color="#87CEFA")
plt.xlabel('所在地区')
plt.ylabel('大学数量')
plt.title('最好大学地区分布图')
plt.xticks(index, adress2)
plt.yticks(pl.np.arange(0, 50, 1))
plt.legend(loc="upper right") # 图例的位置 label="数量"
plt.savefig('huabu.png')
plt.show()
pass
if __name__ == '__main__':
annlysis1()
annlysis2()
pass
五、结果展示