mirror of
https://codeberg.org/icewind/ugc-scaper.git
synced 2026-06-03 18:24:10 +02:00
init
This commit is contained in:
commit
0c58410f6a
11 changed files with 1902 additions and 0 deletions
4
src/data.rs
Normal file
4
src/data.rs
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#[derive(Debug)]
|
||||
pub struct Player {
|
||||
pub name: String,
|
||||
}
|
||||
20
src/error.rs
Normal file
20
src/error.rs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
use thiserror::Error;
|
||||
use miette::Diagnostic;
|
||||
|
||||
#[derive(Debug, Error, Diagnostic)]
|
||||
pub enum ScrapeError {
|
||||
#[error("Failed to request data: {0:#}")]
|
||||
Request(#[from] reqwest::Error),
|
||||
#[error(transparent)]
|
||||
#[diagnostic(transparent)]
|
||||
Parse(#[from] ParseError)
|
||||
}
|
||||
|
||||
#[derive(Debug, Error, Diagnostic)]
|
||||
pub enum ParseError {
|
||||
#[error("Couldn't find expected element '{selector}' for {role}")]
|
||||
ElementNotFound {
|
||||
selector: &'static str,
|
||||
role: &'static str
|
||||
}
|
||||
}
|
||||
18
src/main.rs
Normal file
18
src/main.rs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
mod error;
|
||||
mod parser;
|
||||
pub mod data;
|
||||
|
||||
use main_error::MainResult;
|
||||
use reqwest::get;
|
||||
pub use error::*;
|
||||
use crate::parser::{PlayerParser, Parser};
|
||||
|
||||
pub type Result<T, E = ScrapeError> = std::result::Result<T, E>;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> MainResult {
|
||||
let body = get("https://www.ugcleague.com/players_page.cfm?player_id=76561198024494988").await?.text().await?;
|
||||
let parser = PlayerParser::new();
|
||||
dbg!(parser.parse(&body)?);
|
||||
Ok(())
|
||||
}
|
||||
10
src/parser/mod.rs
Normal file
10
src/parser/mod.rs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
use crate::Result;
|
||||
|
||||
mod player;
|
||||
|
||||
pub use player::*;
|
||||
|
||||
pub trait Parser {
|
||||
type Output;
|
||||
fn parse(&self, document: &str) -> Result<Self::Output>;
|
||||
}
|
||||
35
src/parser/player.rs
Normal file
35
src/parser/player.rs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
use scraper::{Html, Selector};
|
||||
use super::Parser;
|
||||
use crate::{ParseError, Result};
|
||||
use crate::data::Player;
|
||||
|
||||
const SELECTOR_PLAYER_NAME: &str = ".col-md-4 > h3 > b";
|
||||
|
||||
|
||||
pub struct PlayerParser {
|
||||
selector_name: Selector,
|
||||
}
|
||||
|
||||
impl PlayerParser {
|
||||
pub fn new() -> Self {
|
||||
PlayerParser {
|
||||
selector_name: Selector::parse(SELECTOR_PLAYER_NAME).unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Parser for PlayerParser {
|
||||
type Output = Player;
|
||||
|
||||
fn parse(&self, document: &str) -> Result<Self::Output> {
|
||||
let document = Html::parse_document(&document);
|
||||
|
||||
let name = document.select(&self.selector_name).next().ok_or(ParseError::ElementNotFound {
|
||||
selector: SELECTOR_PLAYER_NAME,
|
||||
role: "player name",
|
||||
})?.text().next().unwrap_or_default().to_string();
|
||||
Ok(Player {
|
||||
name
|
||||
})
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue