爬取的是最好大学网软科中国最好大学排名2019
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
五、结果展示