码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 爬虫实训案例:中国大学排名


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

    文章目录

    • 前言🌟
    • 一、🍉从网络上获取大学排名网页内容— getHTMLText()
    • 二、🍉提取网页内容中信息到合适的数据结构— fillUnivList()
    • 三、🍉将数据保存至电脑文件夹中— Store_as_file()
    • 四、🍉主函数
    • 总结🌟


    前言🌟

    本次案例主要涉及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网页中的中的标签下.
      在这里插入图片描述
    • ”学校名称”在
      标签下标签中。
      在这里插入图片描述
      特征:
      的父亲
      标签的属性都是class="link-container"和style="width:200px
      在这里插入图片描述
    • 而”省市“,”类型“,”总分“,”办学层次“等,都是直接在标签的子代中,所以可以直接获取相关数据存放至列表中在这里插入图片描述
    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()
    

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

  • 相关阅读:
    qml实现路径绘制且可编辑
    【C++进阶(七)】仿函数深度剖析&模板进阶讲解
    【App 抓包提示网络异常怎么破?】
    信息学奥赛一本通1000:入门测试题目
    PHP数组处理$arr1转换为$arr2
    apache 模式、优化、功能 与 nginx优化、应用
    HTTPS加密过程详解
    华为分析&联运活动,助您提升游戏总体付费
    背完这套 Java 面试八股文,自动解锁面试牛逼症被动技能
    近世代数之群
  • 原文地址:https://blog.csdn.net/weixin_74994771/article/details/139181394
  • 最新文章
  • 沪漂五周年了:我越来越迷茫了
    Agentic Skill Routing 实战:别再把所有 Skill 塞进 AI Agent 上下文
    MySQL-Seconds_behind_master的精度误差
    [MAF预定义ChatClient中间件-03]CachingChatClient——利用缓存省钱省时间
    AI的至暗历史:从万众期待到被政府撤资,AI的两次死亡徘徊
    Agent OS :五种驯服不确定性的范式
    PortSwigger SQL注入LAB11
    数据库即时编译JIT
    [Begin]AI Learn Data Day 0
    深度学习进阶(二十七)现代 LLM 的核心架构设计其二:SwiGLU
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
小工具 小游戏
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1

京公网安备 11010502049817号