gpt4 book ai didi

web-scraping - 使用 scraper crate 检索兄弟元素

转载 作者:行者123 更新时间:2023-12-05 09:34:23 26 4
gpt4 key购买 nike

在学习 Rust 的过程中,我正在尝试构建一个简单的网络抓取工具。我的目标是抓取 https://news.ycombinator.com/并获取标题、超链接、投票和用户名。为此,我正在使用外部库 reqwestscraper,并编写了一个程序来从该站点抓取 HTML 链接。

Cargo.toml

[package]
name = "stackoverflow_scraper"
version = "0.1.0"
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
scraper = "0.12.0"
reqwest = "0.11.2"
tokio = { version = "1", features = ["full"] }
futures = "0.3.13"

src/main.rs

use scraper::{Html, Selector};
use reqwest;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let url = "https://news.ycombinator.com/";
let html = reqwest::get(url).await?.text().await?;
let fragment = Html::parse_fragment(html.as_str());
let selector = Selector::parse("a.storylink").unwrap();

for element in fragment.select(&selector) {
println!("{:?}",element.value().attr("href").unwrap());
// todo println!("Title");
// todo println!("Votes");
// todo println!("User");
}

Ok(())
}

如何获取对应的标题、投票数和用户名?

最佳答案

首页上的项目存储在 table 中与类 .itemlist .

因为每个项目都是由三个连续的 <tr> 组成的,您必须以三个为一组对它们进行迭代。我选择先收集所有节点。

第一行包含:

  • 职位
  • 域名

第二行包含:

  • 积分
  • 作者
  • 邮寄年龄

第三行是一个应该被忽略的间隔符。

注意:

  • 最近一个小时内创建的帖子似乎不显示任何积分,因此需要相应处理。
  • 广告不包含用户名。
  • 最后两个表格行,tr.morespacetr包含 a.morelink应该被忽略。这就是为什么我选择先 .collect()节点,然后使用 .chunks_exact() .
use reqwest;
use scraper::{Html, Selector};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let url = "https://news.ycombinator.com/";
let html = reqwest::get(url).await?.text().await?;
let fragment = Html::parse_fragment(html.as_str());

let selector_items = Selector::parse(".itemlist tr").unwrap();

let selector_title = Selector::parse("a.storylink").unwrap();
let selector_score = Selector::parse("span.score").unwrap();
let selector_user = Selector::parse("a.hnuser").unwrap();

let nodes = fragment.select(&selector_items).collect::<Vec<_>>();

let list = nodes
.chunks_exact(3)
.map(|rows| {
let title_elem = rows[0].select(&selector_title).next().unwrap();
let title_text = title_elem.text().nth(0).unwrap();
let title_href = title_elem.value().attr("href").unwrap();

let score_text = rows[1]
.select(&selector_score)
.next()
.and_then(|n| n.text().nth(0))
.unwrap_or("0 points");

let user_text = rows[1]
.select(&selector_user)
.next()
.and_then(|n| n.text().nth(0))
.unwrap_or("Unknown user");

[title_text, title_href, score_text, user_text]
})
.collect::<Vec<_>>();

println!("links: {:#?}", list);

Ok(())
}

这应该为您提供以下列表:

[
[
"Docker for Mac M1 RC",
"https://docs.docker.com/docker-for-mac/apple-m1/",
"327 points",
"mikkelam",
],
[
"A Mind Is Born – A 256 byte demo for the Commodore 64 (2017)",
"https://linusakesson.net/scene/a-mind-is-born/",
"226 points",
"matthewsinclair",
],
[
"Show HN: Video Game in a Font",
"https://www.coderelay.io/fontemon.html",
"416 points",
"ghub-mmulet",
],
...
]

或者,可以使用一个可用的 API:

关于web-scraping - 使用 scraper crate 检索兄弟元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66711259/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com