feat(scraping): friend page is now scrapped
This commit is contained in:
parent
c4ef2a129a
commit
73fe9b85a3
3 changed files with 117 additions and 8 deletions
27
froxy-scraper/examples/get_friends.rs
Normal file
27
froxy-scraper/examples/get_friends.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
use froxy_scrapper::{state::State, types::ClusterLocation};
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
async fn main() {
|
||||
let session = std::env::var("FROXY_COOKIE")
|
||||
.expect("provide `FROXY_COOKIE` with the session cookie from you friends42 instance");
|
||||
let state = State::new(session);
|
||||
|
||||
let res = state.get("/friends/", None).await.unwrap();
|
||||
|
||||
let text = res.text().await.unwrap();
|
||||
|
||||
let location = froxy_scrapper::parsing::friend_page(&text);
|
||||
|
||||
for l in &location.friends {
|
||||
println!(
|
||||
"{:^10} | {:^10} | {:^30} | {:^20}",
|
||||
l.login,
|
||||
l.position.as_ref().map(|s| s.as_str()).unwrap_or("<>"),
|
||||
l.last_active.as_ref().map(|s| s.as_str()).unwrap_or("<>"),
|
||||
l.image
|
||||
.as_ref()
|
||||
.map(|s| &s[s.len().saturating_sub(20)..])
|
||||
.unwrap_or("<>")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
use scraper::Selector;
|
||||
use smol_str::SmolStr;
|
||||
use url::Url;
|
||||
|
||||
use crate::types::{ClusterLocation, ClusterLocationData, Relation};
|
||||
use crate::types::{ClusterLocation, ClusterLocationData, Friend, Friends, Relation};
|
||||
|
||||
macro_rules! sel {
|
||||
($name:ident, $value:literal) => {
|
||||
|
|
@ -88,17 +89,17 @@ pub fn get_cluster_location(
|
|||
.has_class("pooled", scraper::CaseSensitivity::AsciiCaseInsensitive);
|
||||
|
||||
let mut relation = Relation::None;
|
||||
if is_me {
|
||||
relation = Relation::Me;
|
||||
}
|
||||
if is_friend {
|
||||
relation = Relation::Friend;
|
||||
if is_pooled {
|
||||
relation = Relation::Pooled;
|
||||
}
|
||||
if is_close_friend {
|
||||
relation = Relation::CloseFriend;
|
||||
}
|
||||
if is_pooled {
|
||||
relation = Relation::Pooled;
|
||||
if is_friend {
|
||||
relation = Relation::Friend;
|
||||
}
|
||||
if is_me {
|
||||
relation = Relation::Me;
|
||||
}
|
||||
if is_focus {
|
||||
relation = Relation::Focus;
|
||||
|
|
@ -119,3 +120,69 @@ pub fn get_cluster_location(
|
|||
|
||||
out
|
||||
}
|
||||
|
||||
sel!(FRIEND_CONT_SEL, "div.container > div > div.card.pl-fix");
|
||||
sel!(FRIEND_CARD_TITLE, "h5.card-title");
|
||||
sel!(FRIEND_LAST_ACTIVE, ".card-text");
|
||||
|
||||
pub fn friend_page(page: impl AsRef<str>) -> Friends {
|
||||
let page = page.as_ref();
|
||||
|
||||
let doc = scraper::Html::parse_document(page);
|
||||
|
||||
let mut out = Friends {
|
||||
friends: Vec::new(),
|
||||
};
|
||||
|
||||
for f in doc.select(&FRIEND_CONT_SEL) {
|
||||
let Some(login) = f
|
||||
.select(&FRIEND_CARD_TITLE)
|
||||
.next()
|
||||
.map(|e| {
|
||||
e.text()
|
||||
.fold(String::new(), |mut acc: String, s: &str| -> String {
|
||||
acc += s;
|
||||
acc
|
||||
})
|
||||
})
|
||||
.map(|s| SmolStr::new(s.trim()))
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
let img = f
|
||||
.select(&IMAGE_SEL)
|
||||
.next()
|
||||
.and_then(|e| e.attr("src"))
|
||||
.map(ToString::to_string);
|
||||
|
||||
let pos_la = f
|
||||
.select(&FRIEND_LAST_ACTIVE)
|
||||
.next()
|
||||
.map(|e| {
|
||||
e.text()
|
||||
.fold(String::new(), |mut acc: String, s: &str| -> String {
|
||||
acc += s;
|
||||
acc
|
||||
})
|
||||
})
|
||||
.map(|s| SmolStr::new(s.trim()))
|
||||
.and_then(|s| {
|
||||
s.split_once(' ')
|
||||
.map(|(pos, last_active)| {
|
||||
(Some(SmolStr::new(pos)), Some(SmolStr::new(last_active)))
|
||||
})
|
||||
.or(Some((Some(s), None)))
|
||||
});
|
||||
out.friends.push(Friend {
|
||||
login,
|
||||
image: img,
|
||||
position: pos_la
|
||||
.as_ref()
|
||||
.and_then(|(pos, _)| pos.clone())
|
||||
.filter(|s| s != "Absent"),
|
||||
last_active: pos_la.as_ref().and_then(|(_, la)| la.clone()),
|
||||
})
|
||||
}
|
||||
|
||||
out
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
use smol_str::SmolStr;
|
||||
|
||||
#[non_exhaustive]
|
||||
#[derive(Debug, Clone, Default, Eq, PartialEq)]
|
||||
pub enum ClusterLocationStatus {
|
||||
|
|
@ -46,3 +48,16 @@ pub struct CluserInformation {
|
|||
pub cluster_name: smol_str::SmolStr,
|
||||
pub locations: Vec<ClusterLocation>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Friend {
|
||||
pub login: SmolStr,
|
||||
pub image: Option<String>,
|
||||
pub position: Option<SmolStr>,
|
||||
pub last_active: Option<SmolStr>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Friends {
|
||||
pub friends: Vec<Friend>,
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue