爬虫实训案例:中国大学排名
近一个月左右的时间学习爬虫,在用所积累的知识爬取了《中国大学排名》这个网站,爬取的内容虽然只是可见的文本,但对于初学者来说是一个很好的练习。在爬取的过程中,通过请求数据、解析内容、提取文本、存储数据等几个重要的内容入手,不过在存储数据后的数据排版方面并不是很完善(优化),希望阅读本文章的学者大大给些存储后的数据排版方面的指点:中文对齐的问题
文章目录
- 前言🌟
- 一、🍉从网络上获取大学排名网页内容— getHTMLText()
- 二、🍉提取网页内容中信息到合适的数据结构— fillUnivList()
- 三、🍉将数据保存至电脑文件夹中— Store_as_file()
- 四、🍉主函数
- 总结🌟
前言🌟
本次案例主要涉及bs4库
中的BeautifulSoup
内容、requests
的使用和存储数据等知识。
提示:以下是本篇文章正文内容,下面案例可供参考
一、🍉从网络上获取大学排名网页内容— getHTMLText()
- 爬取的网址:https://www.shanghairanking.cn/rankings/bcur/202411
- 判断是否可以爬取
在该网站的根目录下查看robots.txt
文件是否可以爬取内容,这里显示没有搜索到该内容
3.利用request库
爬取
def getHTMLText(url):try:r = requests.get(url, timeout=30)r.raise_for_status() # 判断请求是否成功:如果不是200,产生异常requests.HTTPErrorr.encoding = r.apparent_encoding # http header中猜测的响应内容编码方式 设置为 内容中分析出的响应内容编码方式(备选编码方式)return r.textexcept:return "请求失败"
二、🍉提取网页内容中信息到合适的数据结构— fillUnivList()
- 分析网页
我们要爬取的是”排名“,”学校名称“,”省市“,”类型“,”总分“,”办学层次“等信息,如图:
- 先是分析整体信息,需要爬取的文本信息都存放在
.html
网页中的<tbody></tbody>
中的<tr>
标签下.
- ”学校名称”在
<div class="univname" data-v-90b0d2ac>
标签下<a>
标签中。
特征:<a>
的父亲<div>
标签的属性都是class="link-container"和style="width:200px
- 而”省市“,”类型“,”总分“,”办学层次“等,都是直接在
<tr>
标签的子代中,所以可以直接获取相关数据存放至列表中
- 解析数据
获取主要爬取的数据,存放至列表中并返回
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+=1ulist.append(university_data)return ulistexcept: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}'")
四、🍉主函数
代码块
:主函数的书写
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)
最终效果
:当然,我是确实不知道怎么更改,还望读者帮忙提供点意见
总结🌟
总代码块:导入requests库
和bs4库
和bs4库中的BeautifulSoup
import requests
from bs4 import BeautifulSoup
import bs4def getHTMLText(url):try:r = requests.get(url, timeout=30)r.raise_for_status() # 判断请求是否成功:如果不是200,产生异常requests.HTTPErrorr.encoding = r.apparent_encoding # http header中猜测的响应内容编码方式 设置为 内容中分析出的响应内容编码方式(备选编码方式)return r.textexcept: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+=1ulist.append(university_data)return ulistexcept: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()
最后还是想哆嗦一下,希望读者大大,和爬虫感兴趣的多找我讨论讨论,给出点建议和学习上的交流👑👑 👏👏
相关文章:

爬虫实训案例:中国大学排名
近一个月左右的时间学习爬虫,在用所积累的知识爬取了《中国大学排名》这个网站,爬取的内容虽然只是可见的文本,但对于初学者来说是一个很好的练习。在爬取的过程中,通过请求数据、解析内容、提取文本、存储数据等几个重要的内容入…...
C++ IO流
C标准IO流 使用cout进行标准输出,即数据从内存流向控制台(显示器)使用cin进行标准输入,即数据通过键盘输入到程序中使用cerr进行标准错误的输出使用clog进行日志的输出 C文件IO流 文件流对象 ofstream:只写 ofstream 是 C 中用于输出文件…...

debian nginx upsync consul 实现动态负载
1. consul 安装 wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg echo "deb [signed-by/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_r…...
前端基础入门三大核心之HTML篇 —— 同源策略的深度解析与安全实践
前端基础入门三大核心之HTML篇 —— 同源策略的深度解析与安全实践 一、同源策略:定义与起源1.1 定义浅析1.2 何为“源”?1.3 起源与意义 二、同源策略的运作机制2.1 限制范围2.2 安全边界 三、跨越同源的挑战与对策3.1 JSONP3.2 CORS3.3 postMessage 四…...

go 微服务框架 kratos 日志库使用方法及原理探究
一、Kratos 日志设计理念 kratos 日志库相关的官方文档:日志 | Kratos Kratos的日志库主要有如下特性: Logger用于对接各种日志库或日志平台,可以用现成的或者自己实现Helper是在您的项目代码中实际需要调用的,用于在业务代码里…...
VC++位移操作>>和<<以及逻辑驱动器插拔产生的掩码dbv.dbcv_unitmask进行分析的相关代码
VC位移操作>>和<<以及逻辑驱动器插拔产生的掩码dbv.dbcv_unitmask进行分析的相关代码 一、VC位移操作符<<和>>1、右位移操作符 >>:2、左位移操作符 <<: 二、逻辑驱动器插拔产生的掩码 dbv.dbcv_unitmask 进行分析的…...
查看gpu
## 查看gpu信息 if_cuda torch.cuda.is_available() print("if_cuda",if_cuda)gpu_count torch.cuda.device_count() print("gpu_count",gpu_count)...
CSS与表格设计
在网页设计中,表格是一种不可或缺的元素,用于展示和组织数据。虽然HTML提供了基本的表格结构,但通过CSS(层叠样式表)的应用,我们可以极大地提升表格的外观和用户体验。本文将探讨如何利用CSS来设计既美观又…...

阴影映射(线段树)
实时阴影是电子游戏中最为重要的画面效果之一。在计算机图形学中,通常使用阴影映射方法来实现实时阴影。 游戏开发部正在开发一款 2D 游戏,同时希望能够在 2D 游戏中模仿 3D 游戏的光影效果,请帮帮游戏开发部! 给定 x-y 平面上的…...

Docker 容器间通讯
1、虚拟ip/访问 同一网络 安装docker时,docker会默认创建一个内部的桥接网络docker0,每创建一个容器分配一个虚拟网卡,容器之间(包括宿主机)可以根据分配的ip互相访问(ps:其他主机(包括其他主机的容器)无法ping通docker容器ip无法访问&#…...

C语言章节学习归纳--数据类型、运算符与表达式
3.1 C语言的数据类型(理解) 首先,对变量的定义可以包括三个方面: 数据类型 存储类型 作用域 所谓数据类型是按被定义变量的性质,表示形式,占据存储空间的多少,构造特点来划分的。在C语言中&…...

Centos 7.9 使用 iso 搭建本地 YUM 源
Centos 7.9 使用 iso 搭建本地 YUM 源 1 建立挂载点 [rootlocalhost ~]# mkdir -p /media/cdrom/ 2 创建光盘存储路径 [rootlocalhost ~]# mkdir -p /mnt/cdrom/ 3 上传 CentOS-7-x86_64-Everything-2207-02.iso 到 光盘存储路径 [rootlocalhost ~]# ls /mnt/cdrom/ CentOS-…...

NFT Insider #131:Mocaverse NFT市值破3.5万ETH,The Sandbox 参加NFCsummit
引言:NFT Insider由NFT收藏组织WHALE Members(https://twitter.com/WHALEMembers)、BeepCrypto (https://twitter.com/beep_crypto)联合出品,浓缩每周NFT新闻,为大家带来关于NFT最全面、最新鲜、…...

BatBot智慧能源管理平台,更加有效地管理能源
随着能源消耗的不断增加,能源管理已成为全球面临的重要问题。BatBot智慧能源管理作为一种的能源管理技术,促进企业在用能效率及管理有着巨大的提升。 BatBot智慧能源管理是一种基于人工智能技术的能源管理系统,通过智能分析和优化能源使用&…...
医院预约挂号系统微信小程序APP
医院预约挂号小程序,前端后台(后台 java spring boot mysql) 医院预约挂号系统具体功能介绍:展示医院信息、可以注册和登录, 预约挂号(包含各个科室的预约,可以预约每个各个医生)&…...

【代码随想录 二叉树】二叉树前序、中序、后序遍历的迭代遍历
文章目录 1. 二叉树前序遍历(迭代法)2. 二叉树后序遍历(迭代法)3. 二叉树中序遍历(迭代法) 1. 二叉树前序遍历(迭代法) 题目连接 🍎因为处理顺序和访问顺序是一致的。所…...

Error:(6, 43) java: 程序包org.springframework.data.redis.core不存在
目录 一、在做SpringBoot整合Redis的项目时,报错: 二、尝试 三、解决办法 一、在做SpringBoot整合Redis的项目时,报错: 二、尝试 给依赖加版本号,并且把版本换了个遍,也不行,也去update过ma…...

Qt 科目一考试系统(有源码)
项目源码和资源:科目一考试系统: qt实现科目一考试系统 一.项目概述 该项目是一个基于Qt框架开发的在线考试系统,主要实现了考试题目的随机抽取、考试时间限制、成绩统计等功能。用户可以通过界面操作进行考试,并查看自己的考试成绩。 二.技…...

在 Visual Studio 2022 (VS2022) 中删除 Git 分支的步骤如下
git branch -r PS \MauiApp1> git push origin --delete “20240523备份” git push origin --delete “20240523备份”...

玩转OpenHarmony智能家居:如何实现开发版“碰一碰”设备控制
一、简介 “碰一碰”设备控制,依托NFC短距通信协议,通过碰一碰的交互方式,将OpenAtom OpenHarmony(简称“OpenHarmony”)标准系统设备和全场景设备连接起来,解决了应用与设备之间接续慢、传输难的问题&…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...