当前位置: 首页 > news >正文

使用reqwest+select实现简单网页爬虫

这篇文章是一个简单的Rust爬虫示例,我将爬取该网站的图书信息,包括书名、价格和库存状态。使用reqwest库发送HTTP请求,select库解析HTML内容。代码结构清晰,包含错误处理和基本的数据提取逻辑。

适合Rust爬虫新手学习网络请求、HTML解析和数据提取的基本流程。通过这个示例,你可以了解如何构建一个完整的爬虫工作流。

在这里插入图片描述

下面是一个简单、技术成熟且易于理解的 Rust 爬虫教程。我们将创建一个爬取图书信息(标题、价格)的爬虫,目标网站是专为爬虫练习设计的 books.toscrape.com

项目准备

1、创建新项目:

cargo new book_scraper
cd book_scraper

2、添加依赖 (Cargo.toml):

[dependencies]
reqwest = { version = "0.11", features = ["blocking"] } # 同步HTTP客户端
scraper = "0.13"           # HTML解析库
select = "0.5"             # CSS选择器库
anyhow = "1.0"             # 简化错误处理

完整代码 (src/main.rs)

use anyhow::{Context, Result};
use select::document::Document;
use select::predicate::{Class, Name};fn main() -> Result<()> {// 目标网站let url = "http://books.toscrape.com/";// 发送HTTP GET请求let response = reqwest::blocking::get(url).with_context(|| format!("Failed to fetch {}", url))?;// 确保请求成功if !response.status().is_success() {anyhow::bail!("Request failed with status: {}", response.status());}// 读取HTML内容let html_content = response.text().with_context(|| "Failed to read response body")?;// 解析HTML文档let document = Document::from(html_content.as_str());println!("开始爬取: {}", url);println!("{:-^50}", "图书列表");// 查找所有图书条目for book in document.find(Class("product_pod")) {// 提取标题let title = book.find(Name("h3")).next().and_then(|h3| h3.find(Name("a")).next()).map(|a| a.text()).unwrap_or_else(|| "未知标题".to_string());// 提取价格let price = book.find(Class("price_color")).next().map(|p| p.text()).unwrap_or_else(|| "未知价格".to_string());// 提取库存状态let stock = book.find(Class("instock")).next().map(|s| s.text().trim().to_string()).unwrap_or_else(|| "未知库存".to_string());println!("书名: {}", title);println!("价格: {}", price);println!("库存: {}", stock);println!("{}", "-".repeat(40));}println!("爬取完成!共找到 {} 本书", document.find(Class("product_pod")).count());Ok(())
}

代码解析

1、HTTP请求 (reqwest):

let response = reqwest::blocking::get(url)?;

使用同步方式获取网页内容,适合简单爬虫

2、错误处理 (anyhow):

.with_context(|| "错误描述")?;

提供友好的错误信息,自动处理错误传播

3、HTML解析 (select):

let document = Document::from(html_content.as_str());

将HTML内容加载到可查询的文档结构中

4、元素查找:

document.find(Class("product_pod"))

使用CSS选择器查找图书容器

5、数据提取:

book.find(Name("h3")).next().map(|h3| h3.text())

链式调用安全提取元素文本内容

运行结果示例

开始爬取: http://books.toscrape.com/
------------------图书列表------------------
书名: A Light in the Attic
价格: £51.77
库存: In stock
----------------------------------------
书名: Tipping the Velvet
价格: £53.74
库存: In stock
----------------------------------------
... (其他图书) ...
书名: The Black Maria
价格: £22.60
库存: In stock
----------------------------------------
爬取完成!共找到 20 本书

进阶功能添加

1、保存到CSV文件

添加依赖:

csv = "1.1"

修改代码:

use csv::Writer;// 在main函数开头添加:
let mut wtr = Writer::from_path("books.csv")?;
wtr.write_record(&["书名", "价格", "库存"])?;// 在循环内替换打印语句为:
wtr.write_record(&[&title, &price, &stock])?;// 在main函数结尾添加:
wtr.flush()?;
println!("数据已保存到 books.csv");
2、自动翻页
let mut page = 1;
let mut total_books = 0;loop {let url = format!("http://books.toscrape.com/catalogue/page-{}.html", page);// ...爬取逻辑...// 检查是否有下一页if document.find(Class("next")).next().is_none() {break;}page += 1;// 添加延时防止请求过快std::thread::sleep(std::time::Duration::from_secs(1));
}

注意事项

1、尊重网站规则:

  • 添加请求延时(至少1秒)
  • 检查robots.txt(本例中http://books.toscrape.com/robots.txt允许爬取)
std::thread::sleep(std::time::Duration::from_secs(1));

2、处理异常:

  • 网络错误
  • HTML结构变化
.unwrap_or_else(|| "未知".to_string());

3、用户代理设置:

let client = reqwest::blocking::Client::builder().user_agent("Mozilla/5.0 (学习用爬虫)").build()?;
client.get(url).send()?;

这个爬虫包含了爬虫的核心流程:请求 → 解析 → 提取 → 存储,使用成熟稳定的库实现,适合 Rust 新手学习。可根据需求扩展多线程、代理支持等高级功能。

到此就爬取完成!程序统计了找到的图书数量并显示结果。实际应用中,你可以添加CSV保存功能将数据存储到文件,或实现自动翻页爬取全站内容。注意在实际使用时添加请求延时,遵守robots.txt规则,并完善错误处理机制。这个基础爬虫可以扩展为更复杂的项目,如添加代理支持、并发处理或用户登录功能。希望这个示例能帮助你入门Rust爬虫开发!

http://www.dtcms.com/a/327607.html

相关文章:

  • 《Fast Automatic White Balancing Method by Color Histogram Stretching》论文笔记
  • 小米宠物空气净化器好用吗?希喂/小米/范罗士核心性能深度对比
  • 5G专网项目外场常见业务测试指南(六)-PingInfoView
  • 力扣面试150(54/150)
  • 如何构建PHP表单页面及验证相关原理(PHP基础)
  • 六十、【Linux系统lvs应用】LVS简介 、 LVS-NAT集群 、 LVS-DR集群
  • 微服务ETCD服务注册和发现
  • 3 Abp 核心框架(Core Framework)
  • 过程设计工具深度解析-软件工程之详细设计(补充篇)
  • 数字孪生如何推动智慧园区精细化管理
  • CV 医学影像分类、分割、目标检测,之【皮肤病分类】项目拆解
  • OHEM (在线难例挖掘) 详细讲解
  • 【Vue.js】生产设备规划工具(报价单Word文档生成)【开发全流程】
  • 无人机航拍数据集|第14期 无人机水体污染目标检测YOLO数据集3000张yolov11/yolov8/yolov5可训练
  • etcd 备份与恢复
  • Etcd客户端工具Etcd Workbench更新了1.2.0版本!多语言支持了中文,新增了许多快捷功能使用体验再次提升
  • Spark 运行流程核心组件(一)作业提交
  • 干货分享|如何从0到1掌握R语言数据分析
  • 小红书笔记信息获取_实在智能RPA源码解读
  • 邦纳BANNER相机视觉加镜头PresencePLUSP4 RICOH FL-CC2514-2M工业相机
  • C++实现LINGO模型处理程序
  • Java结课案例-景点人数统计的几种场景
  • 日期格式化成英文月,必須指定語言環境
  • Secure CRT做代理转发
  • HTTP应用层协议-长连接
  • 记对外国某服务器的内网渗透
  • C++少儿编程(二十二)—条件结构
  • 机械臂运动规划与控制12讲
  • SQL 语言分类
  • 后端学习路线