Rust 语言教程:使用 Rust 编程进行网络抓取

您所在的位置:网站首页 图片爬虫app下载安装 Rust 语言教程:使用 Rust 编程进行网络抓取

Rust 语言教程:使用 Rust 编程进行网络抓取

#Rust 语言教程:使用 Rust 编程进行网络抓取 | 来源: 网络整理| 查看: 265

安装完成后,关闭终端并再次打开。重新打开终端确保所有环境变量更改都生效。

可以运行以下命令来验证安装:

$ rustc --version rustc 1.63.0 (4b91a6ea7 2022-08-08)用于抓取书籍数据的 Rust 爬虫

为了解如何使用 Rust 爬虫进行抓取,我们来创建真实的网络抓取项目。 

我们将要抓取站点 https://books.toscrape.com/,这是一个用于学习网络抓取的虚拟书店。 它有电商网店应有的各种基本组件。 

设置

第一步,打开终端或命令提示符并创建一个 Rust 编程项目。我们将使用 Cargo 包管理器来搭建项目结构、下载依赖项、编译并运行项目。

打开终端,然后运行以下命令来初始化空白项目,如下所示:

$ cargo new book_scraper

此命令将创建文件夹 book_scraper 并以 Rust 项目所需的文件和文件夹初始化此文件夹。重要文件包括 Cargo.toml 和 src 文件夹中的 main.rs 文件。

在您选择的文本编辑器或 IDE 中打开此文件夹。 

如果您使用的是 Visual Studio Code,我们建议安装一个扩展组件,例如rust-analyzer,以便在 Visual Studio Code 中使用 Rust 环境进行编码。

现在,打开 Cargo.toml 文件,输入以下代码行:

[dependencies] reqwest = {version = "0.11", features = ["blocking"]} scraper = "0.13.0"

这几行代码表明有两个依赖项 - reqwest 和 scraper。我们稍后再来详细讲解。

返回终端并运行以下命令以下载依赖项并编译代码。

$ cargo build Finished dev [unoptimized + debuginfo] target(s) in 0.12s Running `target/debug/book_scraper` Hello, world!

此命令将编译代码以创建可执行文件并运行此文件。可执行文件创建于以下路径:

./target/debug/book_scraper

如果是 Windows 操作系统,文件名为:

.\target\debug\book_scraper.exe

发送 HTTP 请求

要发送 HTTP 请求、GET 或 POST,我们需要 Rust 库。最方便的 Rust 库就是 reqwest。 

该库可以用于两种类型的 http 客户端(http client):异步 http 客户端和阻塞式 http 客户端。

本文旨在介绍使用 Rust 语言进行抓取的基本概况。因此选择阻塞式客户端更适合,更容易跟上教程。这就是我们在 Cargo.toml 中指定我们需要阻塞式功能的原因。

reqwest = {version = "0.11", features = ["blocking"]}

打开 main.rs,在 main() 函数中输入以下几行代码:

fn main() { let url = "https://books.toscrape.com/"; let response = reqwest::blocking::get(url).expect("Could not load url."); let body = response.text().unwrap(); print!("{}",body); }

我们将在第一行代码中存储目标 URL。 

下一行代码是通过阻塞式 http 客户端向此 URL 发送 GET 请求。结果则存储在变量响应中。

之后,从响应中提取 HTML 并将其存储在 body 变量中。这个变量会被打印出来。

保存此文件并在终端输入以下命令行:

$ cargo run

这时输出的是终端上打印的整个 HTML。

用爬虫解析 HTML

要构建网络爬虫,我们需要使用另一个 Rust 库。这个库就被称为 scraper。通过这个库可以使用 CSS 选择器来提取所需的 HTML 元素。

如果您还没有提取,请在依赖项下的 Cargo.toml 文件中输入以下行:

scraper = "0.13.0"

打开 main.rs 文件并输入以下代码行:

let document = Html::parse_document(&body);

在这一行中,我们调用 parse_document 来解析网页。我们将发送使用 reqwest Rust 库提取的原始 HTML。结果是解析后存储在名为 document 的变量中的文档。

可以使用 CSS 选择器查询已解析的 HTML 文档,以定位包含所需信息的 HTML 元素。 

我们可以将这一流程分解成以下三步:

通过 CSS 选择器定位产品;

提取产品描述;

提取产品链接。

有关更多信息,参见以下各个部分。

通过 CSS 选择器定位产品

第一步是确定包含产品相关信息的CSS选择器。在我们的示例中,产品是一本书。

用 Chrome 浏览器打开 https://books.toscrape.com/,并检查网页的 HTML 标记。

您会注意到选择器 article.product_pod 选择了一本书。这说明我们可以对所有这些书籍进行循环并提取个人信息。

首先,在 main.rs 文件的开头添加以下行:

use scraper::{Html, Selector};

接下来,在 main 函数中添加以下行:

let book_selector = Selector::parse("article.product_pod").unwrap();

现在选择器可以使用了。将以下几行添加到 main 函数中:

for element in document.select(&book_selector) { // more code here }

现在我们可以应用更多选择器来提取每本书的信息。

提取产品描述

遍历每个产品描述容器的 HTML 元素,从而轻松编写可重复使用的网页抓取代码。

在此例中,我们要检索产品名称和产品价格。

首先,在 for 循环之前创建两个选择器,如下所示:

let book_name_selector = Selector::parse("h3 a").unwrap(); let book_price_selector = Selector::parse(".price_color").unwrap();

在 for 循环中,将这些选择器用于每本书:

for element in document.select(&book_selector) { let book_name_element = element.select(&book_name_selector).next().expect("Could not select book name."); let book_name = book_name_element.value().attr("title").expect("Could not find title attribute."); let price_element = element.select(&book_price_selector).next().expect("Could not find price"); let price = price_element.text().collect::(); println!("{:?} - {:?}",book_name, price); }

注意两个要点:

书名在 元素的 title 属性中;

价格在文本元素中。

保存文件并在终端运行以下命令:

$ cargo run

这时应该在终端上打印书名和价格。

提取产品链接

可用类似方式提取产品链接。在 for 循环外创建一个选择器,如下所示:

let book_link_selector = Selector::parse("h3 a").unwrap();

在 for 循环中添加以下行:

let book_link_element = element.select(&book_name_selector).next().expect("Could not find book link element."); let book_link= book_link_element.value().attr("href").expect("Could not find href attribute");

我们抓取的所有值现在都可以打印到控制台。而且我们可以将所有内容保存为 CSV,这一点尤佳。

将抓取数据写入 CSV 文件

不创建文件,任何网络抓取项目都不算完整。因此,我们来编写一个 CSV 文件。

我们使用 CSV Rust 库来创建 CSV 文件。

首先,将以下行添加到 Cargo.toml 依赖项中:

csv="1.1"

然后,在 for 循环之前创建一个 CSV 编写器,如下所示:

let mut wtr = csv::Writer::from_path("books.csv").unwrap();

或者,在 for 循环之前编写标头,如下所示:

wtr.write_record(&["Book Name", "Price", "Link"]).unwrap();

在 for 循环中,按以下方式编写每条记录:

wtr.write_record([book_name, &price, &book_link]).unwrap();

最后,在 for 循环之后关闭文件:

wtr.flush().expect("Could not close file");

将所有内容归为一处,main.rs 文件包含以下内容:

// main.rs use scraper::{Html, Selector}; fn main() { let url = "https://books.toscrape.com/"; let response = reqwest::blocking::get(url).expect("Could not load url."); let body = response.text().expect("No response body found."); let document = Html::parse_document(&body); let book_selector = Selector::parse("article.product_pod").expect("Could not create selector."); let book_name_selector = Selector::parse("h3 a").expect("Could not create selector."); let book_price_selector = Selector::parse(".price_color").expect("Could not create selector."); let mut wtr = csv::Writer::from_path("books.csv").expect("Could not create file."); wtr.write_record(&["Book Name", "Price", "Link"]).expect("Could not write header."); for element in document.select(&book_selector) { let book_name_element = element.select(&book_name_selector).next().expect("Could not select book name."); let book_name = book_name_element.value().attr("title").expect("Could not find title attribute."); let price_element = element.select(&book_price_selector).next().expect("Could not find price"); let price = price_element.text().collect::(); let book_link_element = element.select(&book_name_selector).next().expect("Could not find book link element."); let book_link= book_link_element.value().attr("href").expect("Could not find href attribute"); wtr.write_record([book_name, &price, &book_link]).expect("Could not create selector."); } wtr.flush().expect("Could not close file"); println!("Done"); } 总结

本文讲解了如何使用 Rust 语言编写网络爬虫(Rust 爬虫)。我们讨论了如何在 Scraper Rust 库的帮助下,将 CSS 选择器应用于网络爬虫。更多教程,请查看 cURL 博客文章、用 R 或 C# 进行网络抓取。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3