python爬虫爬取最好大学网排名分析地区大学数量分布并绘制柱状图和词云

本人也是初学者,本博客用于python初学者参考使用。

  • 分析网页

本次爬取的是最好大学网软科中国最好大学排名2018:http://www.zuihaodaxue.cn/zuihaodaxuepaiming2018.htmlpython爬虫爬取最好大学网排名分析地区大学数量分布并绘制柱状图和词云

爬取可行性分析:

     理论上,每个网站都会有网络爬虫排除出标准文件robots.txt,这一文件内说明了网站是否可以进行爬取以及可以爬取什么内容。一般网站的robots.txt放置在根目录下,所以可以直接访问进行查看,访问http://www.zuihaodaxue.com/robots.txt结果显示404未找到文件,说明此网站是可以爬取的,本次爬去的网页为静态网页。python爬虫爬取最好大学网排名分析地区大学数量分布并绘制柱状图和词云

通过查看网页源代码知道网页数据存于各个标签中。

 

  • 分析需要的数据

本次爬取所需数据为表格中的排名、学校名称、省市、总分等数据。

经过网页源代码分析发现我所需要的数据都存于<tbody/>标签下的子标签中

 

python爬虫爬取最好大学网排名分析地区大学数量分布并绘制柱状图和词云

而我所需要的排名、学校名称、省市、总分等数据都存放于<tbody/>标签下的<tr></tr>标签下的标签<td> </td>中,因此爬取的数据要提取td标签的内容

 

python爬虫爬取最好大学网排名分析地区大学数量分布并绘制柱状图和词云

  • 创建数据库

本次将爬取数据存入到mysql数据库中,首先创建出对应的数据库表,用于存放爬取的数据。创建数据库表的结构如下:

 

python爬虫爬取最好大学网排名分析地区大学数量分布并绘制柱状图和词云

创建数据库的代码:

CREATE TABLE `daxue1` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `ranking` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,

  `name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,

  `address` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,

  `score` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=3005 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

 

四、代码分析

实现步骤:

  1. 获取指定网页内容
  2. 筛选需要的内容
  3. 存入数据库
  4. 统计各个地区大学数量
  5. 制作大学分布柱状图
  6. 制作词云

对应函数及其意义:

getHTMLText(url):获取网页内容

fillUnivList(ulist,html):获取标签内需要的数据

writeDB(ulist,num):将爬取到的数据存入mysql数据库、

    取出数据统计各个地区大学数量、制作大学地区分数量

    图、制作词云

main():程序入口

 

可行性代码分析:

发送request请求返回一个相应结果reponse对象,判断返回的状态码是否是200,获取网页内容,否则引发异常。

def getHTMLText(url):
    try:
        r=requests.get(url,timeout=30)             r.raise_for_status()                       r.encoding=r.apparent_encoding      

        return r.text
    except:
        return"异常"

使用BeautifulSoup解析获取到的网页源码,并找到我所需内容所在的标签,进行进行精确爬取。

def fillUnivList(ulist,html):
    soup=BeautifulSoup(html,"html.parser")    
    for tr in soup.find('tbody').children:    
        if isinstance(tr,bs4.element.Tag):      
            tds=tr('td')
            ulist.append([tds[0].string,tds[1].string,tds[2].string,tds[3].string])

使用pymysql.connect()方法链接数据库

使用cursor()方法获得python执行Mysql命令的方法

db = pymysql.connect(
    host = 'localhost',
    port=3306,
    user='root',
    password='123456',
    db = 'py',
    charset='utf8'
)
cursor = db.cursor()  

将数据存到mysql数据库中对应的daxue1表中

for i in range(num):
    u=ulist[i]
    sql="INSERT INTO daxue1 (ranking,name,address,score) VALUES ('%s','%s','%s','%s')"% (str(u[0]),str(u[1]),str(u[2]),str(u[3]))
    cursor.execute(sql)

db.commit();

统计各个地区出现的次数,即各个地区大学分布的数量

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 = 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(np.arange(0, 26, 1))
plt.legend(loc="upper right")  #图例的位置 label="数量"
plt.savefig('huabu.png')
plt.show()

 

制作词云:首先将数据库中大学所在地区取出存入ciyun.txt文本中,然后使用jieba分词对文本内容进行分词,并以空格隔开,然后设置词云背景图片,各个参数。

 

wc = WordCloud(background_color="white",  # 设置背景颜色
                mask =image ,  #设置背景图片
               max_words=2000,  # 设置最大显示的字数
               font_path='msyh.ttc',
               # 设置中文字体,使得词云可以显示(词云默认字体是“DroidSansMono.ttf字体库”,不支持中文)
               max_font_size=100,  # 设置字体最大值
               random_state=30,  # 设置有多少种随机生成配色方案
               )
myword = wc.generate(wl)  # 生成词云

# 展示词云图
plt.imshow(myword)
plt.axis("off")  #不显示坐标轴
plt.show()
wc.to_file("ciyun.jpg")
print("词云制作成功")

 

五、结果展示

python爬虫爬取最好大学网排名分析地区大学数量分布并绘制柱状图和词云

 

python爬虫爬取最好大学网排名分析地区大学数量分布并绘制柱状图和词云

源码及其文档链接:https://download.csdn.net/download/qq_38993002/10878766