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

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

文章目录

  • 前言🌟
  • 一、🍉从网络上获取大学排名网页内容— 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.HTTPErrorr.encoding = r.apparent_encoding  # http header中猜测的响应内容编码方式 设置为 内容中分析出的响应内容编码方式(备选编码方式)return r.textexcept: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+=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}'")

四、🍉主函数

  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 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()

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/330404.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

React-router 最佳实践

使用的是 BrowserRouter&#xff0c;Routes 和 Route&#xff0c;这是 react-router-dom v5 和 v6 都支持的 API。这种方式的优点是路由配置和应用的其它部分是紧密集成的&#xff0c;这使得路由配置更加直观和易于理解 // router/index.js import { BrowserRouter as Router,…

【Qt 学习笔记】Qt常用控件 | 布局管理器 | 网格布局Grid Layout

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Qt常用控件 | 布局管理器 | 网格布局Grid Layout 文章编号&#xff1a…

成品短视频APP源码搭建

在数字化时代&#xff0c;短视频已成为全球范围内的流行趋势&#xff0c;吸引了大量的用户和内容创作者。对于有志于进入短视频领域的企业和个人来说&#xff0c;成品短视频APP源码搭建提供了一条快速、高效的路径。本文将探讨成品短视频APP源码搭建的过程及其优势&#xff0c;…

Mac维护神器CleanMyMac X成为你的苹果电脑得力助手

在数字化时代&#xff0c;Mac电脑已成为众多用户的首选。然而&#xff0c;随着频繁的使用和数据量的日益增长&#xff0c;许多Mac用户面临着系统杂乱、存储空间不足以及隐私保护等问题。幸运的是&#xff0c;"CleanMyMac X"这款优化和清理工具应运而生&#xff0c;它…

[论文笔记]REACT: SYNERGIZING REASONING AND ACTING IN LANGUAGE MODELS

引言 今天带来一篇经典论文REACT: SYNERGIZING REASONING AND ACTING IN LANGUAGE MODELS的阅读笔记&#xff0c;论文中文意思是 在语言模型中协同推理和行动。 虽然大型语言模型(LLMs)在语言理解和互动决策任务中展现出强大的能力&#xff0c;但它们在推理(例如思维链提示)和…

【算法】栈算法——最小栈

题解&#xff1a;最小栈(栈算法) 目录 1.题目2.题解3.总结 1.题目 题目链接&#xff1a;LINK 这个题目题意说的有点绕&#xff0c;说白了让你在常数时间内检索到最小元素就是O(1)时间复杂度下找到栈中最小的元素。 2.题解 思路&#xff1a;这个栈可以内嵌套两个库栈来进行…

商品发布功能

文章目录 1.SPU和SKU介绍1.SPU2.SKU3.两者之间的关系 2.完成商品发布界面1.组件引入1.commoditylaunch.vue 引入到 src/views/modules/commodity下2.multiUpload.vue 引入到 src/components/upload/multiUpload.vue 2.创建菜单1.创建目录2.创建菜单&#xff0c;注意菜单路由要匹…

开源博客项目Blog .NET Core源码学习(25:App.Hosting项目结构分析-13)

本文学习并分析App.Hosting项目中后台管理页面的文章管理页面。   文章管理页面用于显示、检索、新建、编辑、删除文章数据&#xff0c;以便在前台页面的首页、文章专栏、文章详情页面显示文章数据。文章管理页面附带一新建及编辑页面&#xff0c;以支撑新建和编辑文章数据。…

交换机部分综合实验

实验要求 1.内网IP地址使用172.16.0.0/16 2.sw1和sW2之间互为备份; 3.VRRP/mstp/vlan/eth-trunk均使用; 4.所有pc均通过DHcP获取Ip地址; 5.ISP只配置IP地址; 6.所有电脑可以正常访问IsP路由器环回 实验拓扑 实验思路 1.给交换机创建vlan&#xff0c;并将接口划入vlan 2.在SW1和…

传输层 --- UDP

一、简述与回顾 传输层&#xff1a;负责数据能够从发送端传输接收端 在TCP/IP协议中&#xff0c;我们用"源IP"&#xff0c;"源端口号"&#xff0c;"目的IP"&#xff0c;"目的端口号"&#xff0c;和"协议号"来表示一个通信。…

Android studio关闭自动更新

Windows下&#xff1a; 左上角file - setting - Appearance & Behavier - system setting - update - 取消勾选

golang通过go-aci适配神通数据库

1. go-aci简介 go-aci是神通数据库基于ACI(兼容Oracle的OCI)开发的go语言开发接口&#xff0c;因此运行时需要依赖ACI驱动和ACI库的头文件。支持各种数据类型的读写、支持参数绑定、支持游标范围等操作。 2. Linux部署步骤 2.1. Go安装&#xff1a; 版本&#xff1a;1.9以上…

Spring Cache基本使用

Spring 从 3.1 版本开始定义缓存抽象来统一不同的缓存技术&#xff1b;在应用层面与后端存储之间&#xff0c;提供了一层抽象&#xff0c;这层抽象目的在于封装各种可插拔的后端存储( ehcache, redis, guava)&#xff0c;最小化因为缓存给现有业务代码带来的侵入。 一、Spring…

机器学习实验 --- 逻辑回归

第1关:逻辑回归核心思想 任务描述 本关任务:根据本节课所学知识完成本关所设置的编程题 #encoding=utf8 import numpy as npdef sigmoid(t):完成sigmoid函数计算:param t: 负无穷到正无穷的实数:return: 转换后的概率值:可以考虑使用np.exp()函数#********** Begin *******…

C语言-atoi()库函数的模拟实现

文章目录 前言一、atoi()库函数的介绍及使用1.1 atoi()库函数介绍1.2 atoi()库函数使用 二、atoi()库函数的模拟实现2.1 函数设计2.2 函数实现思路2.3 具体实现2.4 测试 总结 前言 本篇文章介绍c语言中库函数atoi()的使用&#xff0c;以及模拟实现库函数。 一、atoi()库函数的…

景源畅信电商:抖店需要的成本高吗?

在数字化时代的浪潮中&#xff0c;短视频平台迅速崛起&#xff0c;成为连接用户与商家的新桥梁。抖音作为其中的佼佼者&#xff0c;不仅改变了人们的娱乐方式&#xff0c;也催生了新型的电商模式——抖店。许多人好奇&#xff0c;入驻这样一个充满活力的平台&#xff0c;需要承…

【数据结构】第七节:堆

个人主页&#xff1a; 深情秋刀鱼-CSDN博客 数据结构专栏&#xff1a;数据结构与算法 源码获取&#xff1a;数据结构: 上传我写的关于数据结构的代码 (gitee.com) ​ 目录 一、堆 1.堆的概念 2.堆的定义 二、堆的实现 1.初始化和销毁 2.插入 向上调整算法 3.删除 向下调整算法…

DDoS攻击的最新动态及市场趋势分析

随着数字化转型的加速和网络连接设备的增加&#xff0c;分布式拒绝服务(Distributed Denial of Service, DDoS)攻击已经成为全球网络安全领域的一大威胁。根据最新的市场研究报告&#xff0c;预计到2028年&#xff0c;DDoS防护软件市场的复合年增长率将达到14%以上&#xff0c;…

Threes 特效 炫酷传送门HTML5动画特效

基于Three.js的HTML5 3D动画&#xff0c;这个动画模拟了游戏中的一个炫酷的3D场景&#xff0c;支持360度视角查看&#xff0c;也支持鼠标滚轮进行缩放。画面中主要展现了一个游戏中传送门的效果&#xff0c;同时还有路两边的围栏、灯笼、石头&#xff0c;以及星光闪闪的萤火虫&…

springboot vue 开源 会员收银系统 (2) 搭建基础框架

前言 完整版演示 前面我们对会员系统https://blog.csdn.net/qq_35238367/article/details/126174288进行了分析 确定了技术选型 和基本的模块 下面我们将从 springboot脚手架开发一套收银系统 使用脚手架的好处 不用编写基础的rabc权限系统将工作量回归业务本身生成代码 便于…