用Rust实现web信息抓取
优采云 发布时间: 2022-06-22 01:59用Rust实现web信息抓取
假设你想从一个网站上获得一些信息,比如股票价格、最新的广告等信息。最简单的方法是调用一个API请求所需的信息,如果该网站有免费API的话。如果没有的话,还有第二种选择:网页抓取。
你不需要连接到一个“官方”资源,你可以使用一个机器人来抓取网站的内容并解析以找到你需要的东西。
在本文中,你将学习如何使用Rust实现web抓取。你将使用两个Rust库,requestwest和scraper,从IMDb中抓取前100部电影列表。
创建项目
首先,你需要创建一个基本的Rust项目,并添加将使用的所有依赖。这最好用Cargo完成。生成一个Rust二进制项目,运行:
cargo new web_scraper
接下来,将所需的库添加到依赖中。对于这个项目,将使用requestwest和scraper。在你最喜欢的代码编辑器中打开web_scraper文件夹并打开cargo.toml文件。在文件的最后,添加库:
[dependencies]<br />reqwest = {version = "0.11", features = ["blocking"]}scraper = "0.12.0"
现在你可以移动到src/main.rs,开始编写web信息抓取程序。
获取网站的HTML
抓取页面通常包括获取页面的HTML代码,然后解析它以找到所需的信息。因此,需要在Rust程序中使用IMDb页面的代码。要做到这一点,首先需要了解浏览器是如何工作的,因为它们是与网页交互的常用方式。
HTTP有各种不同类型的请求,例如GET(用于获取资源的内容)和POST(用于向服务器发送信息)。要在Rust程序中获得IMDb网页的代码,您需要通过向IMDb发送HTTP get请求来模拟浏览器的行为。
在Rust中,你可以使用reqwest crate。这个常用的Rust库提供了HTTP客户端的特性。它可以做很多普通浏览器可以做的事情,比如打开页面、登录和存储cookie。
要请求页面的代码,可以使用requestwest::blocking::get方法:
fn main() { let response = reqwest::blocking::get("https://www.imdb.com/search/title/?groups=top_100&sort=user_rating,desc&count=100") .unwrap() .text() .unwrap();}
response现在将包含请求页面的完整HTML代码。
从HTML中提取信息
web抓取项目中最难的部分通常是从HTML文档中获取你需要的特定信息。为了达到这个目的,Rust中一个常用的工具是scraper库。它的工作原理是将HTML文档解析为树状结构。可以使用CSS选择器查询感兴趣的元素。
第一步是使用库解析你获取的整个HTML:
let document = scraper::Html::parse_document(&response);
接下来,找到并选择需要的部件。要做到这一点,需要检查网站的代码,并找到唯一标识这些条目的CSS选择器集合。
最简单的方法是通过浏览器,找到你需要的元素,然后检查该元素的代码:
对于IMDb,你需要的元素是电影的名称。当你检查元素时,你会看到它被包装在一个标签中:
The Shawshank Redemption
不幸的是,这个标签不是唯一的。由于页面上有很多标签,将它们全部抓取不是一个明智的主意,因为其中大多数都不是你需要的条目。相反,找到电影标题唯一的标记,然后导航到该标记内的。在这种情况下,你可以选择lister-item-header类:
1. The Shawshank Redemption (1994)
现在需要使用scraper::Selector::parse方法创建一个查询。
使用h3.lister-item-header>a选择器。它表示找到了标记,该标记的父标记为标记,该标记属于一个lister-item-header类。使用方式如下:
let title_selector = scraper::Selector::parse("h3.lister-item-header>a").unwrap();
现在可以使用select方法将此查询应用于已解析的文档。为了获得电影的实际标题而不是HTML元素,你需要将每个HTML元素映射到它内部的HTML:
let titles = document.select(&title_selector).map(|x| x.inner_html());
titles现在是一个迭代器,包含所有前100个标题的名称。
你现在要做的就是把这些名字打印出来。要做到这一点,首先标题列表进行zip。然后在得到的迭代器上调用for_each方法,它将在单独的一行上打印迭代器中的每一项:
titles.zip(1..101).for_each(|(item, number)| println!("{}. {}", number, item));
现在,你的web信息抓取器完成了。如果你保存文件并使用cargo run运行它,你将获得前100部电影的列表:
1. The Shawshank Redemption2. The Godfather3. The Dark Knight4. The Lord of the Rings: The Return of the King5. Schindler's List6. The Godfather: Part II7. 12 Angry Men8. Pulp Fiction9. Inception10. The Lord of the Rings: The Two Towers...
总结
在本教程中,你学习了如何使用Rust创建一个简单的web信息抓取器。根据你的需要,有许多方法可以升级这个web信息抓取器。
然而,有时使用CSS选择器是不够的。您可能需要更高级的解决方案来模拟真实浏览器所采取的操作。在这种情况下,你可以使用thirtyfour库,用于更强大的web抓取操作。
本文翻译自: