使用 Python 爬取某网站简历模板(bs4/lxml+协程)
使用 Python 爬取站长素材简历模板
简介
在本教程中,我们将学习如何使用 Python 来爬取站长素材网站上的简历模板。我们将使用requests和BeautifulSoup库来发送 HTTP 请求和解析 HTML 页面。本教程将分为两个部分:第一部分是使用BeautifulSoup的方法,第二部分是使用lxml的方法,并比较两者的差异。
环境准备
首先,确保你已经安装了 Python。然后,安装以下库:
pip install requests beautifulsoup4 lxml
方法一:使用 BeautifulSoup
1.导入库
import requests
from bs4 import BeautifulSoup
import os
2.创建文件夹用于保存爬取的简历图片
if not os.path.exists("resume_templates_images"):os.makedirs("resume_templates_images")
3.爬取第一页
first_page_url = "https://sc.chinaz.com/jianli/free.html"
response = requests.get(first_page_url)
response.encoding = 'utf-8'if response.status_code == 200:soup = BeautifulSoup(response.text, 'html.parser')templates = soup.find_all('div', class_='box col3 ws_block')for template in templates:link = template.find('a', target='_blank')['href']img = template.find('img')['src']if img.startswith('//'):img = 'https:' + imgtitle = template.find('p').find('a').text.strip()img_response = requests.get(img)if img_response.status_code == 200:img_name = f"{title.replace(' ', '_')}.jpg"img_path = os.path.join("resume_templates_images", img_name)with open(img_path, 'wb') as f:f.write(img_response.content)else:print(f"下载图片 {img} 失败,状态码: {img_response.status_code}")
4.爬取第二页到第五页
在这里插入代base_url = "https://sc.chinaz.com/jianli/free_"
for page_num in range(2, 6):url = f"{base_url}{page_num}.html"response = requests.get(url)response.encoding = 'utf-8'if response.status_code == 200:soup = BeautifulSoup(response.text, 'html.parser')templates = soup.find_all('div', class_='box col3 ws_block')for template in templates:link = template.find('a', target='_blank')['href']img = template.find('img')['src']if img.startswith('//'):img = 'https:' + imgtitle = template.find('p').find('a').text.strip()img_response = requests.get(img)if img_response.status_code == 200:img_name = f"{title.replace(' ', '_')}.jpg"img_path = os.path.join("resume_templates_images", img_name)with open(img_path, 'wb') as f:f.write(img_response.content)else:print(f"下载图片 {img} 失败,状态码: {img_response.status_code}")
码片
方法二:使用 lxml
first_page_url = "https://sc.chinaz.com/jianli/free.html"
response = requests.get(first_page_url)
response.encoding = 'utf-8'if response.status_code == 200:tree = etree.HTML(response.text)templates = tree.xpath('//div[@class="box col3 ws_block"]')for template in templates:link = template.xpath('.//a[@target="_blank"]/@href')[0]img = template.xpath('.//img/@src')[0]if img.startswith('//'):img = 'https:' + imgtitle = template.xpath('.//p/a[@class="title_wl"]/text()')[0].strip()img_response = requests.get(img)if img_response.status_code == 200:img_name = f"{title.replace(' ', '_')}.jpg"img_path = os.path.join("resume_templates_images", img_name)with open(img_path, 'wb') as f:f.write(img_response.content)else:print(f"下载图片 {img} 失败,状态码: {img_response.status_code}")
同方法一,但使用lxml的xpath方法。
方法比较
• 解析速度:lxml通常比BeautifulSoup快,特别是在处理大型 HTML 文档时。
• 易用性:BeautifulSoup提供了更直观的方法来查找元素,如find和find_all,而lxml使用xpath,这可能需要更多的学习。
• 灵活性:xpath在定位复杂的 HTML 结构时更加灵活,但也需要更复杂的查询。
通过运行我们发现这段代码的执行时间较长,那么我们有没有方法来缩短运行时间呢
import asyncio
import aiohttp
from bs4 import BeautifulSoup
import os
import time # 导入time模块来记录时间# 创建一个文件夹resume_templates_images用于保存图片
if not os.path.exists("resume_templates_images"):os.makedirs("resume_templates_images")# 用于存储所有页面的模板数据
all_template_data = []async def fetch(session, url):async with session.get(url) as response:return await response.text()async def parse_page(session, url):soup = BeautifulSoup(await fetch(session, url), 'html.parser')templates = soup.find_all('div', class_='box col3 ws_block')for template in templates:link = template.find('a', target='_blank')['href']img = template.find('img')['src']if img.startswith('//'):img = 'https:' + imgtitle = template.find('p').find('a').text.strip()async with session.get(img) as img_response:if img_response.status == 200:img_name = f"{title.replace(' ', '_')}.jpg"img_path = os.path.join("resume_templates_images", img_name)with open(img_path, 'wb') as f:f.write(await img_response.read())all_template_data.append({'title': title,'img_url': img,'link': link})async def main():start_time = time.time() # 记录开始时间async with aiohttp.ClientSession() as session:# 处理第一页await parse_page(session, "https://sc.chinaz.com/jianli/free.html")# 处理第二页到第五页for page_num in range(2, 6):url = f"https://sc.chinaz.com/jianli/free_{page_num}.html"await parse_page(session, url)# 输出所有页面的模板数据for idx, data in enumerate(all_template_data, 1):print(f"模板 {idx}:")print(f"名称: {data['title']}")print(f"图片链接: {data['img_url']}")print(f"模板链接: {data['link']}")print("=" * 50)end_time = time.time() # 记录结束时间run_time = end_time - start_time # 计算运行时间print(f"程序运行时间:{run_time:.2f}秒")if __name__ == "__main__":asyncio.run(main())
这段代码是一个使用asyncio和aiohttp库来异步爬取站长素材网站上的简历模板的 Python 脚本。以下是代码的详细解释和如何加快爬取速度的说明:
• parse_page 函数:一个异步函数,用于解析页面内容,提取模板链接和图片链接,并下载图片。
• 异步 I/O:使用asyncio和aiohttp可以实现异步 I/O 操作,这意味着在等待网络响应时,程序可以执行其他任务,而不是被阻塞。这样可以显著提高爬取效率,特别是在需要处理多个页面时。

这段代码是顺序并发执行执行每个页面的爬取,有没有更快的方式——并发执行
• 并发请求:使用asyncio.gather来同时启动多个parse_page任务。
修改代码以实现并发请求
以下是如何修改main函数来实现并发请求:
async def main():start_time = time.time() # 记录开始时间async with aiohttp.ClientSession() as session:# 处理第一页tasks = [parse_page(session, "https://sc.chinaz.com/jianli/free.html")]# 处理第二页到第五页,并发执行for page_num in range(2, 6):url = f"https://sc.chinaz.com/jianli/free_{page_num}.html"tasks.append(parse_page(session, url))# 等待所有页面处理完成await asyncio.gather(*tasks)# 输出所有页面的模板数据for idx, data in enumerate(all_template_data, 1):print(f"模板 {idx}:")print(f"名称: {data['title']}")print(f"图片链接: {data['img_url']}")print(f"模板链接: {data['link']}")print("=" * 50)end_time = time.time() # 记录结束时间run_time = end_time - start_time # 计算运行时间print(f"程序运行时间:{run_time:.2f}秒")if __name__ == "__main__":asyncio.run(main())
在这个修改后的版本中,所有的页面爬取任务都被添加到一个列表中,然后使用asyncio.gather来并发执行这些任务。这样可以同时发送多个请求,而不是等待一个请求完成后再发送下一个请求,从而加快整体的爬取速度。


import asyncio
import aiohttp
from bs4 import BeautifulSoup
import os
import time
import aiofiles# 创建一个文件夹resume_templates_images用于保存图片
if not os.path.exists("resume_templates_images"):os.makedirs("resume_templates_images")# 用于存储所有页面的模板数据
all_template_data = []
#async with aiohttp.ClientSession() as session
async def fetch(session, url):async with session.get(url) as response:return await response.text()#返回字符串形式的响应数据async def parse_page(session, url):soup = BeautifulSoup(await fetch(session, url), 'html.parser')templates = soup.find_all('div', class_='box col3 ws_block')for template in templates:link = template.find('a', target='_blank')['href']img = template.find('img')['src']if img.startswith('//'):img = 'https:' + imgtitle = template.find('p').find('a').text.strip()async with session.get(img) as img_response:if img_response.status == 200:file_type = ".jpg.rar"# 以rar压缩文件的形式储存img_name = f"{title.replace(' ', '_')+file_type}"# 更改保存的格式仅需修改img_path = os.path.join("resume_templates_images", img_name)async with aiofiles.open(img_path, 'wb') as f:await f.write(await img_response.read())# read()返回二进制数据all_template_data.append({'title': title,'img_url': img,'link': link})async def main():start_time = time.time() # 记录开始时间async with aiohttp.ClientSession() as session:# 创建任务列表tasks = []# 处理第一页task = asyncio.create_task(parse_page(session, "https://sc.chinaz.com/jianli/free.html"))tasks.append(task)# 处理第二页到第五页,并发执行for page_num in range(2, 6):url = f"https://sc.chinaz.com/jianli/free_{page_num}.html"task = asyncio.create_task(parse_page(session, url))tasks.append(task)# 等待所有页面处理完成 挂起任务列表 asyncio.gather 是 Python asyncio 模块中的一个函数,它用于并发地运行多个协程,并且等待它们全部完成。# asyncio.gather 的作用类似于 asyncio.wait,但它不仅等待协程完成,还会返回一个包含所有结果的列表。await asyncio.gather(*tasks)# 输出所有页面的模板数据for idx, data in enumerate(all_template_data, 1):print(f"模板 {idx}:")print(f"名称: {data['title']}")print(f"图片链接: {data['img_url']}")print(f"模板链接: {data['link']}")print("=" * 50)end_time = time.time() # 记录结束时间run_time = end_time - start_time # 计算运行时间print(f"程序运行时间:{run_time:.2f}秒")if __name__ == "__main__":asyncio.run(main())
相关文章:
使用 Python 爬取某网站简历模板(bs4/lxml+协程)
使用 Python 爬取站长素材简历模板 简介 在本教程中,我们将学习如何使用 Python 来爬取站长素材网站上的简历模板。我们将使用requests和BeautifulSoup库来发送 HTTP 请求和解析 HTML 页面。本教程将分为两个部分:第一部分是使用BeautifulSoup的方法&am…...
深度学习模型中音频流式处理
音频流式处理的介绍 在现代深度学习应用中,音频处理是一个重要的领域,尤其是在语音识别、音乐生成和音频分类等任务中。流式处理(Streaming Processing)是一种有效的处理方式,它允许模型逐帧处理音频数据,…...
C语言(字符数组和字符指针)
字符串实现 在C语言中,表示一个字符串有以下两种形式: 用字符数组存放一个字符串。用字符指针指向一个字符串。 案例 #include <stdio.h>/*** 方式1:使用字符数组实现字符串*/ void str_test1(){// 定义一个伪字符串char str[] &q…...
SkyWalking Helm Chart 4.7.0 安装、配置
https://skywalking.apache.org/events/release-apache-skywalking-kubernetes-helm-chart-4.7.0/https://github.com/apache/skywalking-helm/tree/v4.7.0https://skywalking.apache.org/zh/2020-04-19-skywalking-quick-start/简介 skywalking 是分布式系统的 APM(Applicat…...
微搭低代码AI组件单词消消乐从0到1实践
目录 1 为什么要开发单词消消乐2 需要具备什么功能3 采用什么技术方案实现4 逻辑设计4.1 数据结构设计4.2 游戏的核心逻辑4.3 数据设计 5 代码详解5.1 导入依赖5.2 定义函数组件5.3 数据初始化5.4 状态定义5.5 打乱解释的逻辑5.6 定义选择单词的函数5.7 定义选择解释的函数5.8 …...
23种设计模式之中介者模式
目录 1. 简介2. 代码2.1 Mediator (中介者接口)2.2 ChatRoom (具体中介者类)2.3 User (同事接口)2.4 ChatUser (具体同事类)2.5 Test (测试)2.6 运行结果 3. …...
【Golang】Go语言编程思想(六):Channel,第六节,并发编程模式
并发模式 下例重新对 channel 的用法进行回顾: package mainimport ("fmt""math/rand""time" )func msgGen(name string) chan string {c : make(chan string)go func(name string) { // 在这个 goroutine 当中向外发送数据i : 0fo…...
unity打包web,如何减小文件体积,特别是 Build.wasm.gz
unity打包WebGL,使用的是wasw,最终生成的Build.wasm.gz体积很大,有6.5M,有几个方法可以稍微减小这个文件的大小 1. 裁剪引擎代码: 此步可将大小从6.5减小到 6.2(此项默认开启,只是改了裁剪等级…...
go引入skywalking
前置条件:安装好jdk11,linux服务器(centos7.9),go版本(我的是1.18,1.21都可以) 1.下载skywalking Downloads | Apache SkyWalking 2.下载agent源码 Downloads | Apache SkyWalkin…...
大华DSS数字监控系统 attachment_downloadAtt.action 任意文件下载漏洞复现
0x01 产品描述: 大华 DSS 数字监控系统是大华开发的一款安防视频监控系统,拥有实时监视、云台操作、录像回放、报警处理、设备管理等功能。0x02 漏洞描述: 大华DSS数字监控系统 attachment_downloadAtt.action接口存在任意文件读取漏洞,未经身份验证攻击者可通过该漏洞读取…...
qt 封装 调用 dll
这个目录下 ,第一个收藏的这个 ,可以用, 但是有几个地方要注意 第一.需要将dll的头文件添加到qt的文件夹里面 第二,需要在pro文件里面添加动态库路径 第三,如果调用dll失败,那么大概需要将dll文件放在e…...
Python使用Selenium库获取 网页节点元素、名称、内容的方法
我们要用到一些网页源码信息,例如获取一些节点的class内容, 除了使用Beautifulsoup来解析,还可以直接用Selenium库打印节点(元素)名称,用来获取元素的文本内容或者标签名。 例如获取下面的class的内容&am…...
系统安全——访问控制访问控制
访问控制 概念 什么是访问控制 access control 为用户对系统资源提供最大限度共享的基础上,对用户的访问权进行管理,防止对信息的非授权篡改和滥用 访问控制作用 保证用户在系统安全策略下正常工作 拒绝非法用户的非授权访问请求 拒绝合法用户越权…...
SQL Server 数据库还原到某个时点(完整恢复模式)
将 SQL Server 数据库还原到某个时点(完整恢复模式) 适用范围: SQL Server 本主题介绍如何使用 SQL Server Management Studio 或 Transact-SQL 将数据库还原到 SQL Server 中的某个时间点。 本主题仅与使用完整恢复模式或大容量日志恢复模…...
埃隆马斯克X-AI发布Grok-2大模型,快来体验~
引言 近年来,人工智能技术的快速发展推动了大语言模型的广泛应用。无论是日常生活中的智能助手,还是行业中的自动化解决方案,大语言模型都扮演着越来越重要的角色。2024年,X-AI推出了新一代的大模型——Grok-2,这款模…...
Python工厂设计模式:简化对象创建
Python工厂设计模式:简化对象创建 引言什么是工厂模式?简单工厂模式示例定义基类和子类创建工厂类使用工厂创建对象 优点使用场景总结 引言 在编程中,我们经常需要创建不同的对象,但有时创建对象的逻辑可能会变得复杂。工厂设计模…...
【隐私计算篇】隐私集合求交(PSI)原理深入浅出
隐私集合求交技术是多方安全计算领域的一个子问题,通常也被称为安全求交、隐私保护集合交集或者隐私交集技术等,其目的是允许持有各自数据集的双方或者多方,执行两方或者多方集合的交集计算,当PSI执行完成,一方或者两方…...
工作中常用的8种设计模式
前言 设计模式在我们日常的软件开发中无处不在,它们帮助我们编写更易扩展、更具可读性的代码。 今天结合我实际工作场景和源码实例,跟大家一起聊聊工作中最常用的8种设计模式,希望对你会有所帮助。 1. 单例模式 单例模式确保一个类只有一…...
Qwen 论文阅读记录
本文仅作自己初步熟悉大模型,梳理之用,慢慢会更改/增加/删除,部分细节尚未解释,希望不断学习之后,能够完善补充。若有同道之人,欢迎指正探讨。 关于后面的code-qwen and math-qwen,我个人认为依…...
自动驾驶:百年演进
亲爱的小伙伴们😘,在求知的漫漫旅途中,若你对深度学习的奥秘、JAVA 、PYTHON与SAP 的奇妙世界,亦或是读研论文的撰写攻略有所探寻🧐,那不妨给我一个小小的关注吧🥰。我会精心筹备,在…...
告别手动截图!用Python脚本从ROS bag文件里精准提取带时间戳的图片(附完整代码)
告别手动截图!用Python脚本从ROS bag文件里精准提取带时间戳的图片(附完整代码) 在计算机视觉和机器人研究中,从ROS bag文件中高效提取带时间戳的图像数据是构建数据集的关键步骤。传统方法依赖ROS自带工具,但常面临提…...
FOIL框架实战:用不变学习破解时间序列预测的OOD难题
1. 当时间序列预测遇上OOD难题:从业务痛点说起 去年冬天,我接手了一个零售销量预测项目。客户兴奋地展示着他们在历史数据上达到95%准确率的LSTM模型,但实际部署后,这个"明星模型"在新年促销季的预测误差突然飙升到40%。…...
构建实时体积渲染管线:Unreal VDB插件深度解析与实践指南
构建实时体积渲染管线:Unreal VDB插件深度解析与实践指南 【免费下载链接】unreal-vdb This repo is a non-official Unreal plugin that can read OpenVDB and NanoVDB files in Unreal. 项目地址: https://gitcode.com/gh_mirrors/un/unreal-vdb 在实时渲染…...
解决跨平台资源下载难题:res-downloader高效资源获取工具全解析
解决跨平台资源下载难题:res-downloader高效资源获取工具全解析 【免费下载链接】res-downloader 资源下载器、网络资源嗅探,支持微信视频号下载、网页抖音无水印下载、网页快手无水印视频下载、酷狗音乐下载等网络资源拦截下载! 项目地址: https://gi…...
利用爱毕业aibiye等智能软件,论文写作与编程工作流程得到革新,AI为学术研究提供新思路
文章总结表格(工具排名对比) 工具名称 核心优势 aibiye 精准降AIGC率检测,适配知网/维普等平台 aicheck 专注文本AI痕迹识别,优化人类表达风格 askpaper 快速降AI痕迹,保留学术规范 秒篇 高效处理混AIGC内容&…...
基于COMSOL光学仿真的光子晶体光纤与微纳光学研究
comsol光学仿真光子晶体光纤,comsol光学方方向COMLOS微纳光学,仿真双芯光子晶体光,锥形光纤 光子晶体光光纤滤波器等,bpm,rsoft,fullware,论文复现在光学仿真领域,COMSOL Multiphysi…...
QT:Tab Widget的进阶应用与实战技巧
1. Tab Widget的动态管理技巧 第一次用QT做带标签页的界面时,我习惯在设计器里把Tab页都固定好。直到接手一个需要动态加载配置文件的仪表盘项目,才发现动态增删Tab才是真实开发中的常态。比如用户点击"新建图表"按钮时,我们需要实…...
从Kaggle竞赛到真实业务:聊聊那些年我们用错的AI算法和开源库
从Kaggle竞赛到真实业务:聊聊那些年我们用错的AI算法和开源库 在数据科学社区里,Kaggle竞赛排行榜和真实业务需求之间,似乎永远隔着一道看不见的鸿沟。那些在竞赛中斩获高分的神奇模型,一旦放进生产环境,常常表现得像…...
3步解锁抖音无水印下载神器:让内容备份效率提升10倍的完整指南
3步解锁抖音无水印下载神器:让内容备份效率提升10倍的完整指南 【免费下载链接】douyin-downloader 项目地址: https://gitcode.com/GitHub_Trending/do/douyin-downloader 在数字内容爆炸的时代,抖音已成为知识传播、文化交流和创意展示的重要平…...
Apache Doris 4.0.4:解锁数据管理新境界
Apache Doris 4.0 作为重要里程碑发布后,社区通过 4.0.1 至 4.0.4 版本快速演进。如今 4.0.4 正式登场,功能更稳定可靠,引领其从实时分析迈向数据管理领域。面向 AI 工作负载的混合搜索能力检索成现代数据平台核心负载,Apache Dor…...
