Skip to content

Instantly share code, notes, and snippets.

@drogus
Created December 23, 2018 13:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save drogus/1791b3197a614008d8aa61287c5d5e6d to your computer and use it in GitHub Desktop.
Save drogus/1791b3197a614008d8aa61287c5d5e6d to your computer and use it in GitHub Desktop.
[dependencies]
tokio = { version = "0.1", features = ["async-await-preview"] }
reqwest = "0.9.5"
select = "0.4.2"
futures = "0.1.25"
#![feature(async_await, await_macro, futures_api)]
extern crate reqwest;
extern crate select;
extern crate futures;
use std::io::{Cursor};
use select::document::Document;
use select::predicate::{Attr, Name, Predicate};
use reqwest::r#async::{Client, Decoder};
use std::error::Error;
use std::fmt;
use std::num;
use std::mem;
use futures::{Stream};
use {
tokio::await,
};
#[derive(Debug)]
enum APError {
Request(reqwest::Error),
Io(std::io::Error),
Parse(num::ParseIntError),
PageNotFound(reqwest::Response),
}
impl From<reqwest::Error> for APError {
fn from(err: reqwest::Error) -> APError {
APError::Request(err)
}
}
impl From<num::ParseIntError> for APError {
fn from(err: num::ParseIntError) -> APError {
APError::Parse(err)
}
}
impl From<std::io::Error> for APError {
fn from(err: std::io::Error) -> APError {
APError::Io(err)
}
}
impl fmt::Display for APError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
APError::Io(ref err) => err.fmt(f),
APError::Request(ref err) => err.fmt(f),
APError::Parse(ref err) => err.fmt(f),
APError::PageNotFound(ref response) => {
write!(f, "Page not found for url {}", response.url())
}
}
}
}
impl Error for APError {
fn description(&self) -> &str {
match *self {
APError::Io(ref err) => err.description(),
APError::Request(ref err) => err.description(),
APError::Parse(ref err) => err.description(),
APError::PageNotFound(ref _response) => "Page not found",
}
}
}
async fn auction_ids() -> Result<Vec<u64>, APError> {
let url = "https://www.ebay.de/sch/i.html?_nkw=colchester+drehmaschine";
let mut response = await!(Client::new().get(url).send())?;
let chunks = await!{mem::replace(response.body_mut(), Decoder::empty()).concat2()}?;
let body = Cursor::new(chunks);
let mut ids: Vec<u64> = Vec::new();
let document = Document::from_read(body)?;
for node in document.find(
Attr("id", "ResultSetItems")
.child(Attr("id", "ListViewInner"))
.child(Name("li")),
) {
let id = node.attr("listingid")
.and_then(|str| Some(str.parse::<u64>().unwrap_or(0)))
.unwrap_or(0);
if id > 0 {
ids.push(id);
}
}
Ok(ids)
}
fn main() {
tokio::run_async(async {
let result = await! { auction_ids() };
match result {
Ok(ids) => {
for i in ids {
println!("{}", i);
}
},
Err(e) => eprintln!("{}", e)
}
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment