一、开发背景

(一)爬虫技术概述

网络爬虫(又称为网页蜘蛛,网络机器人,在FOFA社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。

网络爬虫应用智能自构造技术,随着不同主题的网站,可以自动分析构造URL去重。网络爬虫使用多线程技术,让爬虫具备更强大的抓取能力。对网络爬虫的连接网络设置连接及读取时间,避免无限制的等待。为了适应不同需求,使网络爬虫可以根据预先设定的主题实现对特定主题的爬取。研究网络爬虫的原理并实现爬虫的相关功能,并将爬去的数据清洗之后存入数据库,后期可视化显示。

定向网络爬虫可以帮助人们快速地从庞大的互联网中获取特定的信息,是当今信息时代非常有用的助手。Python 是一门面向对象、解释型高级程序设计语言,语法简洁清晰,具有丰富强大的类库。使用网络爬虫可以批量采集数据,大大提高数据分析的速度和效率。Python语言简洁、高效,被称“胶水语言”,具有丰富的第三方库,处理网页和链接非常方便。本文介绍了网络爬虫的类型、工作原理以及Python爬虫技术所需的第三方库,构建了爬取中国大学排名数据的程序。

(二)Python简介

Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。Python 的设计具有很强的可读性,相比其他语言经常使用英文关键字,其他语言的一些标点符号,它具有比其他语言更有特色语法结构。

Python是一种解释型语言:这意味着开发过程中没有了编译这个环节。类似于PHP和Perl语言。

Python是交互式语言:这意味着,您可以在一个Python提示符 >>> 后直接执行代码。

Python是面向对象语言:这意味着Python支持面向对象的风格或代码封装在对象的编程技术。

Python是初学者的语言:Python 对初级程序员而言,是一种伟大的语言,它支持广泛的应用程序开发,从简单的文字处理到 WWW 浏览器再到游戏。

(三)本文要点

随着科技发展,大数据越来越重要,日渐增加,准确全面地获取数据可以帮助学生日常学习选择等,具有相当重要的研究价值。基于Python的网络动态排名数据抓取方案利用requests库抓取Ajax异步请求多页数据源,抓取的内容更为全面;对抓取到的排名数据进行统计分析,对多线程效率进行对比分析,显示爬虫具有良好的适应性。该方案抓取的网络资讯在科研、选择等方面具有一定实用价值。

二、使用“库”的分析

(一)“库”的简介

本文使用的Python第三方库主要有:requests库、beautifulsoup4库、json库。

①requests库

Python提供了多个用来编写爬虫程序的库,Requests是Python的第三方库,这个库的宗旨是“让 HTTP 服务于人类”。Requests库是在urllib 的基础上开发而来,它使用Python语言编写,并且采用了Apache2 Licensed(一种开源协议)的HTTP 库。与urllib相比,Requests更加方便、快捷,因此在编写爬虫程序时Requests库使用较多。

Requests是Python的第三方库,它的安装非常简便,如下所示:

python -m pip install requests

1)Requests 库常用请求方法:

requests.get()该方法用于 GET请求,表示向网站发起请求,获取页面响应对象。

requests.post()该方法用于POST请求,先由用户向目标url提交数据,然后服务器返回一个HttpResponse响应对象。

Requests库常用方法及参数介绍:Requests库中定义了七个常用的请求方法,这些方法各自有着不同的作用,在这些请求方法中requests.get() 与requests.post()方法最为常用。请求方法如下(表 1)所示:

1  常用请求方法

2)Requests 库应用实例:

#获取网页源代码

【源代码】

import requests #调用requests库

res = requests.get('https://www.shanghairanking.cn/rankings/bcur/2021')

#获取网页源代码,得到的res是Response对象

res.encoding = 'UTF-8'

txt = res.text #字符串

txt = txt.encode() #把str转化成byte

with open('D:\编程\代码\课程设计\中国大学排名html代码.txt','wb') as f:

    f.write(txt)

    f.close()

print('完成')

【运行结果:图 1】

1  Requests 库应用实例

②beautifulsoup4库

Beautiful Soup简称BS4(其中4表示版本号)是一个Python第三方库,它可以从HTML或XML文档中快速地提取指定的数据。

由于Bautiful Soup是第三方库,因此需要单独下载,下载方式非常简单,执行以下命令即可安装:

pip install bs4

由于BS4解析页面时需要依赖文档解析器,所以还需要安装lxml作为解析库:

pip install lxml

Python也自带了一个文档解析库html.parser,但是其解析速度要稍慢于lxml。除了上述解析器外,还可以使用html5lib解析器,安装方式如下:

pip install html5lib

BS4常用语法:

Tag节点,标签(Tag)是组成HTML文档的基本元素。在BS4中,通过标签名和标签属性可以提取出想要的内容。

遍历节点,Tag 对象提供了许多遍历tag节点的属性,比如 contents、children用来遍历子节点;parent与parents用来遍历父节点;而 next_sibling与previous_sibling则用来遍历兄弟节点 。

find_all()与find(),find_all()与 find()是解析HTML文档的常用方法,它们可以在HTML文档中按照一定的条件(相当于过滤器)查找所需内容。

CSS选择器,BS4 支持大部分的 CSS 选择器,比如常见的标签选择器、类选择器、id 选择器,以及层级选择器。Beautiful Soup 提供了一个 select() 方法,通过向该方法中添加选择器,就可以在 HTML 文档中搜索到与之对应的内容。

③json库

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,遵循欧洲计算机协会制定的 JavaScript 规范(简称 ECMAScript)。JSON 易于人阅读和编写,同时也易于机器解析和生成,能够有效的提升网信息的传输效率,因此它常被作为网络、程序之间传递信息的标准语言,比如客户端与服务器之间信息交互就是以 JSON 格式传递的。

简单地说,JSON 可以将 JavaScript 对象表示的一组数据转换为字符串格式,以便于在网络、程序间传输这个字符串。并且在需要的时候,您还可以将它转换为编程语言所支持的数据格式。本节主要介绍如何实现 JSON 数据与 Python 数据类型间的相互转换。

Python 语言内置了专门处理 JOSN 数据的模块——jons 模块,通过该模块就可以完成 JSON 与 Python 两种数据格式的相互转换。

表 2  JSON方法总结

jons.loads()该方法可以将 json 格式的字符串转换成 Python 对象(比如列表、字典、元组、整型以及浮点型),其中最常用的是转换为字典类型。

json.dump()它可以将 Python 对象(字典、列表等)转换为 json 字符串,并将转换后的数据写入到 json 格式的文件中 ,因此该方法必须操作文件流对象。比如当使用爬虫程序完成数据抓取后,有时需要将数据保存为 json 格式,此时就用到了 json.dump() 方法,

json.load()该方法用于操作文件流对象,不过它与 dump() 恰好相反,它表示从  json 文件中读取 JSON 字符串,并将读取内容转换为 Python 对象。

json.dumps()该方法可以将 Python 对象转换成 JSON 字符串。

综上所述 json.load() 与 json.dump() 操作的是文件流对象,实现了 json 文件的读写操作,而 json.loads() 与 json.dumps() 操作的是 Python 对象或者 JOSN 字符串。

④xlwings库

xlwings是一个BSD许可Python库,可以很容易地从Excel调用Python,反之亦然:

Scripting: 使用接近VBA的语法从Python自动化/与Excel交互。

Macros: 用干净而强大的Python代码替换VBA宏。

UDFs: 在Python中编写用户定义函数(UDF)(仅限Windows)。

REST API: 通过REST API操作Excel工作簿。

完全支持Numpy arrays 和Pandas Series/DataFrames . xlwings-powered workbooks are easy to distribute and work on Windows and Mac。

(二)可行性分析

robots协议:定向爬虫网址是否提供robots协议的约定,由于我们只访问了这个网站的一个链接,可以手动查看。

输入:http://www.zuihaodaxue.cn/robots.txt

图 2  

发现网页不存在,说明这个网站并没有通过robots协议对爬虫进行相应的限制,因此我们对大学排名的爬取是可以实现的。

三、实例设计

(一)实例详细介绍

获取中国大学排名的爬虫实例,采用了requests和BeautifulSoup4函数库;

中国大学排名网址:

https://www.shanghairanking.cn/api/pub/v1/bcur?bcur_type=11&year=2021

功能描述:输入大学排名URL连接,输出大学排名信息的屏幕输出(排名,大学名称,总分,类型);技术路线:requests和bs4;定向爬虫:仅对输入URL进行爬取,不扩展爬取。

def getHTMLText(url):网络上获取大学排名网页内容,def fillUnivList(text, num):提取网页内容中信息到合适的数据结构:def printUnivList(ulist):利用数据结构展示并输出结果。

(二)实例流程分析

实例流程结构图如(图 3)所示:

3  实例流程结构图

步骤一:从网络上获取大学排名的网页内容getHTMLText();步骤二:提取网页内容中信息到合适的数据结构 fillUnivList();步骤三:利用数据结构展示并输出结果printUnivList()使用这三个模块是结果更加清晰可读。

(三)实例运行环境

实例运行结果如下(图 4):

4  实例运行环境

运行环境如下(图 5):

5  运行环境

运行平台:

Windows10

运行环境:

PyCharm Community Edition 2020.2.3

解释器:python3.9

(四)程序设计

【源代码】

import requests

import json

headers = {

    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36\ (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36'}

url='https://www.shanghairanking.cn/api/pub/v1/bcur?bcur_type=11&year=2021'

def getHTMLText(url):

    '''网络上获取大学排名网页内容'''

    try:

        r = requests.get(url, headers=headers,timeout=40)

        # #如果状态不是200,就会引发HTTPError异常

        r.raise_for_status()

        r.encoding = r.apparent_encoding

        return r.text

    except:

        return ""

def fillUnivList(text, num):

    # response = requests.get(url, timeout=40)

    # text = response.text

    data = json.loads(text)

    content = data['data']['rankings']

    ulist = []

    for i in range(num):

        index = content[i]['rankOverall']

        name = content[i]['univNameCn']

        score = content[i]['score']

        category = content[i]['univCategory']

        ulist.append([index, name, score, category])

    return ulist

def printUnivList(ulist):

    # 打印前 num 名的大学

    #tplt ="{0:^10}\t{1:^10}\t{2:^10}\t{3:^10}"

    tplt = "{0:^10}\t{1:{3}^10}\t{2:^10}\t{4:^10}"   # {1:{3}^10} 中的 {3} 代表取第三\个参数

    print(tplt.format("排名 ", "学校名称", "总分", chr(12288), "类型"))  # chr(12288)\ 代表中文空格

    for i in range(10):

        u = ulist[i]

        # chr(12288) 代表中文空格

        print(tplt.format(u[0], u[1], u[2], chr(12288), u[3]))

if __name__ == '__main__':

    text=getHTMLText(url)

    ulist=fillUnivList(text, 10)

printUnivList(ulist)

(五)程序优化

利用requests、BeautifulSoup、xlwings库抓取软科中国大学排名首页数据,并且保存至Excel表中。

【步骤】

  • 软科中国大学排名。(https://www.shanghairanking.cn/rankings/bcur/2021)
  • 调用requests模块中get方法,get方法包括headers参数,访问上述网址,获取Response 对象。
  • 利用BeautifulSoup类解析。
  • 利用find_all等方法查找tr、td等标签对象。
  • 将找到的相应标签内容依次添加到列表中。
  • 利用xlwings库,将列表内容写入Excel文件。
  • 将获取排名数据封装为一个方法。
  • 将抽取排名信息封装为一个方法。
  • main()方法完成整体调用。

【源程序】

import requests as re

from bs4 import BeautifulSoup

import bs4

import xlwings as xw

def getSoup(url):

    try:

        headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4)\ AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36'}

        web=re.get(url,timeout=30,headers=headers)

        web.encoding=web.apparent_encoding

        #BeautifulSoup将字节流转换为utf-8编码

        bs_obj=BeautifulSoup(web.text,'lxml')

        return bs_obj

    except:

        return ""

def findUniversity(soup):

    ulist=[['排名','univ-logo','学校中文名称','学校英文名称','备注','省市','类型','总\分','办学层次']]

    for tr in soup.tbody.find_all('tr'):

        if isinstance(tr, bs4.element.Tag):

            tds = tr.find_all('td')

            ulist.append([tds[0].text.strip(),

                          tds[1].find(class_="univ-logo").get('src'),

                          tds[1].find(class_="name-cn").text.strip(),

                          tds[1].find(class_="name-en").text.strip(),

                          tds[1].find(class_="tags").text.strip(),

                          tds[2].text.strip(),

                          tds[3].text.strip(),

                          tds[4].text.strip(),

                          tds[5].text.strip()])

    return ulist

def main():

    #获取BeautifulSoup对象

    url = "https://www.shanghairanking.cn/rankings/bcur/2021"

    soup = getSoup(url)

    uinfo = findUniversity(soup)

    #写入Excel文件

    wb=xw.Book()

    sht=wb.sheets('Sheet1')

    sht.range('a1').value=uinfo#将数据添加到表格中

    wb.save('D:\编程\代码\课程设计\大学排名数据.xlsx')

    wb.close()

if __name__ == "__main__":

    main()

【运行结果:图 6】

6  运行结果

四、小结

通过此次课程设计,使我更加扎实的掌握了python爬虫方面的知识,在设计过程中虽然遇到了一些问题,但经过一次又一次的思考,一遍又一遍的检查终于找出了原因所在,也暴露出了前期我在这方面的知识欠缺和经验不足。实践出真知,通过亲自动手制作,使我们掌握的知识不再是纸上谈兵。

在课程设计过程中,我们持续发现错误,持续改正,持续领悟,持续获取。最终的检测调试环节,本身就是在践行“过而能改,善莫大焉”的知行观。这次课程设计终于顺利完成了,在设计中遇到了很多问题,最后在老师的指导下,终于游逆而解。在今后社会的发展和学习实践过程中,一定要不懈努力,不能遇到问题就想到要退缩,一定要不厌其烦的发现问题所在,然后一一实行解决,只有这样,才能成功的做成想做的事,才能在今后的道路上劈荆斩棘,而不是知难而退,那样永远不可能收获成功,收获喜悦,也永远不可能得到社会及他人对你的认可!

回顾起此课程设计,至今我仍感慨颇多,从理论到实践,在这段日子里,能够说得是苦多于甜,但是能够学到很多很多的东西,同时不但能够巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提升自己的实际动手水平和独立思考的水平。在设计的过程中遇到问题,能够说得是困难重重,但可喜的是最终都得到了解决。

实验过程中,也对团队精神的实行了考察,让我们在合作起来更加默契,在成功后一起体会喜悦的心情。果然是团结就是力量,只有互相之间默契融洽的配合才能换来最终完美的结果。

五、参考文献

[1]Python语言在大数据分析中的应用[J].冯艳茹.电脑知识与技术. 2020(24).

[2]Python网络爬虫实例教程[M].人民邮电出版社,齐文光,2018.

[3]Python语言程序设计基础[M].高等教育出版社,嵩天,2017.

[4]Python爬虫技术的网页数据抓取与分析[J].徐志,金伟.数字技术与应用.2020(10).

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐