爬虫实训案例:中国大学排名

近一个月左右的时间学习爬虫,在用所积累的知识爬取了《中国大学排名》这个网站,爬取的内容虽然只是可见的文本,但对于初学者来说是一个很好的练习。在爬取的过程中,通过请求数据、解析内容、提取文本、存储数据等几个重要的内容入手,不过在存储数据后的数据排版方面并不是很完善(优化),希望阅读本文章的学者大大给些存储后的数据排版方面的指点:中文对齐的问题


前言🌟

本次案例主要涉及bs4库中的BeautifulSoup内容、requests的使用和存储数据等知识。

在这里插入图片描述


提示:以下是本篇文章正文内容,下面案例可供参考

一、🍉从网络上获取大学排名网页内容— getHTMLText()

  1. 爬取的网址:https://www.shanghairanking.cn/rankings/bcur/202411
  2. 判断是否可以爬取
    在该网站的根目录下查看robots.txt文件是否可以爬取内容,这里显示没有搜索到该内容,则是网站是可用爬取的。
    在这里插入图片描述

3.利用request库爬取

def getHTMLText(url):
    try:
        r = requests.get(url, timeout=30)
        r.raise_for_status()  # 判断请求是否成功:如果不是200,产生异常requests.HTTPError
        r.encoding = r.apparent_encoding  # http header中猜测的响应内容编码方式 设置为 内容中分析出的响应内容编码方式(备选编码方式)
        return r.text
    except:
        return "请求失败"

二、🍉提取网页内容中信息到合适的数据结构— fillUnivList()

  1. 分析网页
    我们要爬取的是”排名“,”学校名称“,”省市“,”类型“,”总分“,”办学层次“等信息,如图:
  • 先是分析整体信息,需要爬取的文本信息都存放在.html网页中的<tbody></tbody>中的<tr>标签下.
    在这里插入图片描述
  • ”学校名称”在<div class="univname" data-v-90b0d2ac>标签下<a>标签中。
    在这里插入图片描述
    特征:<a>的父亲<div>标签的属性都是class="link-container"和style="width:200px
    在这里插入图片描述
  • 而”省市“,”类型“,”总分“,”办学层次“等,都是直接在<tr>标签的子代中,所以可以直接获取相关数据存放至列表中在这里插入图片描述
  1. 解析数据
    获取主要爬取的数据,存放至列表中并返回
def fillUnivList(ulist, html):
    soup = BeautifulSoup(html, 'html.parser')  # 设置BeautifulSoup解析器为'html.parser'
    soup.prettify()  # 整理解析的网页
    
    # 创建列表
    tds_name = []
    name_types = []
    tds_location = []
    tds_type = []
    tds_total = []
    tds_level = []
    try:
        # 遍历tbody的下行遍历
        for tr in soup.tbody.children:
            # 检测tr标签的类型的类型,如果tr标签的类型不是bs4库定义的tag类型,将过滤掉
            if isinstance(tr, bs4.element.Tag):  # 检查变量tr是否为BeautifulSoup库中Tag类的实例的一个条件判断语句
                # tds=str(list(tr('td')[2])[0]).strip()
                # 学校名称
                td_name = tr('td')[1]
                td_div_names = td_name.find_all('div', attrs={"style": "width:200px", "class": "link-container"})
                for div_tag in td_div_names:
                    # 另一种写法
                    # name_part = div_tag.find('a').get_text(strip=True).split('\n', 1)[0]
                    a = str(div_tag.find_all('a')[0].string).strip().split('\n')[0]
                    tds_name.append(a)
                # 学校类型
                td_name_type = tr('td')[1] \
                    .find_all('div', attrs={"class": "univname"})[0] \
                    .find_all('p', attrs={"class": "tags"})[0].get_text(strip=True)
                # 位置
                td_location = tr('td')[2].get_text(strip=True)
                # 类型
                td_type = tr('td')[3].get_text(strip=True)
                # 总分
                td_total = tr('td')[4].get_text(strip=True)
                # 办学层次
                td_level = tr('td')[5].get_text(strip=True)
                # 将各个数据添加至列表
                name_types.append(td_name_type)
                tds_location.append(td_location)
                tds_type.append(td_type)
                tds_total.append(td_total)
                tds_level.append(td_level)
                # break
        # 中文名字列表
        name_cns = tds_name[::2]
        # 英文名字列表
        name_ens = tds_name[1::2]
        i=1
        # 遍历列表大学信息,存放至空列表university中,使用zip打包,zip打包后的数据是元组
        for name_cn, name_en, name_type, location, type, total, level in \
                zip(name_cns, name_ens, name_types, tds_location, tds_type, tds_total, tds_level):
            university_data = {
                '序号':i,
                '学校名称': name_cn + " " + name_en + " " + name_type,
                '省市': location,
                '类型': type,
                '总分': total,
                '办学层次': level
            }
            i+=1
            ulist.append(university_data)
        return ulist
    except:
        return "爬取失败"

三、🍉将数据保存至电脑文件夹中— Store_as_file()

这里直接给出代码块,因为完全没有真的优化处理好爬取后的数据(还是很杂乱)

def Store_as_file(path,datas):
    # 打开文件准备写入
    with open(path, 'w', encoding='utf-8') as file:
        # 写入表头,方便阅读
        file.write("{:^10}\t{:<110}\t{:<10}\t{:<10}\t{:<10}\t{:>10}\n".format("序号","学校名称","省市","类型","总分","办学层次"))
        t="\t"*10
        # file.write(f"序号\t学校名称\t\t省市\t\t类型\t\t总分\t\t办学层次\n")
        # 遍历列表,将每个字典的内容写入文件
        for university in datas:
            # 使用制表符分隔各个字段,保证对齐
            line = "{序号:^10}\t{学校名称:<110}\t{省市:<10}\t{类型:<10}\t{总分:<10}\t{办学层次:>10}\n".format(**university)
            file.write(line)

    print(f"数据已成功保存至'{path}'")

四、🍉主函数

  1. 代码块:主函数的书写
def main():
    university = []
    num = int(input("请输入大学排名的年份:"))
    url=f"https://www.shanghairanking.cn/rankings/bcur/{num}11"
    html=getHTMLText(url)
    datas=fillUnivList(university,html)
    path=input("请输入存放内容的位置:")
    Store_as_file(path,datas)
  1. 最终效果:当然,我是确实不知道怎么更改,还望读者帮忙提供点意见

在这里插入图片描述

总结🌟

总代码块:导入requests库bs4库和bs4库中的BeautifulSoup

import requests
from bs4 import BeautifulSoup
import bs4

def getHTMLText(url):
    try:
        r = requests.get(url, timeout=30)
        r.raise_for_status()  # 判断请求是否成功:如果不是200,产生异常requests.HTTPError
        r.encoding = r.apparent_encoding  # http header中猜测的响应内容编码方式 设置为 内容中分析出的响应内容编码方式(备选编码方式)
        return r.text
    except:
        return "请求失败"

def fillUnivList(ulist, html):
    soup = BeautifulSoup(html, 'html.parser')  # 设置BeautifulSoup解析器为'html.parser'
    soup.prettify()  # 整理解析的网页

    # 创建列表
    tds_name = []
    name_types = []
    tds_location = []
    tds_type = []
    tds_total = []
    tds_level = []
    try:
        # 遍历tbody的下行遍历
        for tr in soup.tbody.children:
            # 检测tr标签的类型的类型,如果tr标签的类型不是bs4库定义的tag类型,将过滤掉
            if isinstance(tr, bs4.element.Tag):  # 检查变量tr是否为BeautifulSoup库中Tag类的实例的一个条件判断语句
                # tds=str(list(tr('td')[2])[0]).strip()
                # 学校名称
                td_name = tr('td')[1]
                td_div_names = td_name.find_all('div', attrs={"style": "width:200px", "class": "link-container"})
                for div_tag in td_div_names:
                    # 另一种写法
                    # name_part = div_tag.find('a').get_text(strip=True).split('\n', 1)[0]
                    a = str(div_tag.find_all('a')[0].string).strip().split('\n')[0]
                    tds_name.append(a)
                # 学校类型
                td_name_type = tr('td')[1] \
                    .find_all('div', attrs={"class": "univname"})[0] \
                    .find_all('p', attrs={"class": "tags"})[0].get_text(strip=True)
                # 位置
                td_location = tr('td')[2].get_text(strip=True)
                # 类型
                td_type = tr('td')[3].get_text(strip=True)
                # 总分
                td_total = tr('td')[4].get_text(strip=True)
                # 办学层次
                td_level = tr('td')[5].get_text(strip=True)
                # 将各个数据添加至列表
                name_types.append(td_name_type)
                tds_location.append(td_location)
                tds_type.append(td_type)
                tds_total.append(td_total)
                tds_level.append(td_level)
                # break
        # 中文名字列表
        name_cns = tds_name[::2]
        # 英文名字列表
        name_ens = tds_name[1::2]
        i=1
        # 遍历列表大学信息,存放至空列表university中,使用zip打包,zip打包后的数据是元组
        for name_cn, name_en, name_type, location, type, total, level in \
                zip(name_cns, name_ens, name_types, tds_location, tds_type, tds_total, tds_level):
            university_data = {
                '序号':i,
                '学校名称': name_cn + " " + name_en + " " + name_type,
                '省市': location,
                '类型': type,
                '总分': total,
                '办学层次': level
            }
            i+=1
            ulist.append(university_data)
        return ulist
    except:
        return "爬取失败"

def Store_as_file(path,datas):
    # 打开文件准备写入
    with open(path, 'w', encoding='utf-8') as file:
        # 写入表头,方便阅读
        file.write("{:^10}\t{:<110}\t{:<10}\t{:<10}\t{:<10}\t{:>10}\n".format("序号","学校名称","省市","类型","总分","办学层次"))
        t="\t"*10
        # file.write(f"序号\t学校名称\t\t省市\t\t类型\t\t总分\t\t办学层次\n")
        # 遍历列表,将每个字典的内容写入文件
        for university in datas:
            # 使用制表符分隔各个字段,保证对齐
            line = "{序号:^10}\t{学校名称:<110}\t{省市:<10}\t{类型:<10}\t{总分:<10}\t{办学层次:>10}\n".format(**university)
            file.write(line)

    print(f"数据已成功保存至'{path}'")

def main():
    university = []
    num = int(input("请输入大学排名的年份:"))
    url=f"https://www.shanghairanking.cn/rankings/bcur/{num}11"
    html=getHTMLText(url)
    datas=fillUnivList(university,html)
    path=input("请输入存放内容的位置:")
    Store_as_file(path,datas)

if __name__ == '__main__':
    main()

最后还是想哆嗦一下,希望读者大大,和爬虫感兴趣的多找我讨论讨论,给出点建议和学习上的交流👑👑 👏👏

  • 61
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
### 回答1: 您好!关于爬取大学排名的信息,可以使用 Python 中的 requests 和 BeautifulSoup 库来实现。 首先,需要确定目标网站并分析其网页结构。以中国大学排名网站(http://www.zuihaodaxue.com/zuihaodaxuepaiming2020.html)为例,我们可以看到该网页中包含了大学排名的信息。 然后,使用 requests 库获取该网站的 HTML 代码。代码如下: ``` import requests url = 'http://www.zuihaodaxue.com/zuihaodaxuepaiming2020.html' response = requests.get(url) html = response.content ``` 接着,使用 BeautifulSoup 库来解析 HTML 代码,并提取出需要的排名信息。代码如下: ``` from bs4 import BeautifulSoup soup = BeautifulSoup(html, 'html.parser') table = soup.find('tbody') rows = table.find_all('tr') for row in rows: cols = row.find_all('td') print(cols[0].text, cols[1].text, cols[2].text, cols[3].text, cols[4].text) ``` 以上代码会输出大学的排名、学校名称、省份、总分和指标得分。 需要注意的是,爬取网站信息时要尊重网站的相关规定,并避免对网站造成过大的负担。 ### 回答2: Python大学排名爬虫是一种用于自动获取大学排名信息的程序。它利用Python编程语言的强大功能和第三方库,使用网络爬虫技术从相关网站抓取大学排名数据,然后进行数据解析和处理,并将结果显示或保存到本地。 首先,Python大学排名爬虫需要选择一个合适的目标网站,该网站提供了大学排名的信息。可以使用Python的requests库来向目标网站发送HTTP请求,并使用BeautifulSoup库解析网页内容,提取排名数据。这些库都是Python中常用的网络爬虫工具。 其次,Python大学排名爬虫需要编写相应的代码来定位目标排名信息所在的HTML标签或CSS选择器,并从中提取数据。可以使用BeautifulSoup库的强大的查找功能和提取方法来实现这一步骤。 接着,Python大学排名爬虫需要将抓取的数据进行清洗和整理。可以使用Python的字符串处理函数、正则表达式或其他相关工具对数据进行清洗和格式化。 最后,Python大学排名爬虫可以将抓取到的数据显示在屏幕上,或者保存到本地文件中,以供后续的数据分析或其他用途。 总的来说,Python大学排名爬虫是一种能够自动获取大学排名信息的应用程序,它借助Python编程语言和相关的网络爬虫工具,实现了从目标网站抓取数据、数据解析和清洗,并将结果显示或保存的功能。该爬虫技术在获取大量数据时非常便捷高效,为教育研究、学生选择大学等提供了便利。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不知道写什么的作者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值