#![allow(clippy::all)]
#![allow(
dead_code,
unused_imports,
unused_variables,
non_snake_case,
rustdoc::all
)]
use crate::core::{Client, Error, Method, QueryParams, Result};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::collections::HashMap;
#[derive(Clone)]
pub struct Web {
client: Client,
}
impl Web {
pub(crate) fn new(client: Client) -> Self {
Self { client }
}
pub fn client(&self) -> &Client {
&self.client
}
pub async fn detect_protection(
&self,
params: DetectProtectionParams,
) -> Result<DetectProtectionResponse> {
let path = "/v1/web/detect".to_string();
let query: Vec<(String, String)> = Vec::new();
let mut body = serde_json::Map::new();
if let Some(v) = ¶ms.country {
body.insert("country".to_string(), serde_json::json!(v));
}
if let Some(v) = ¶ms.timeout {
body.insert("timeout".to_string(), serde_json::json!(v));
}
if let Some(v) = ¶ms.url {
body.insert("url".to_string(), serde_json::json!(v));
}
let body = if body.is_empty() {
None
} else {
Some(Value::Object(body))
};
self.client.send(Method::POST, &path, &query, body).await
}
pub async fn scrape_url(&self, params: ScrapeUrlParams) -> Result<ScrapeUrlResponse> {
let path = "/v1/web/scrape".to_string();
let query: Vec<(String, String)> = Vec::new();
let mut body = serde_json::Map::new();
if let Some(v) = ¶ms.ai_extract {
body.insert("ai_extract".to_string(), serde_json::json!(v));
}
if let Some(v) = ¶ms.ai_prompt {
body.insert("ai_prompt".to_string(), serde_json::json!(v));
}
if let Some(v) = ¶ms.anti_bot {
body.insert("anti_bot".to_string(), serde_json::json!(v));
}
if let Some(v) = ¶ms.country {
body.insert("country".to_string(), serde_json::json!(v));
}
if let Some(v) = ¶ms.custom_headers {
body.insert("custom_headers".to_string(), serde_json::json!(v));
}
if let Some(v) = ¶ms.engine {
body.insert("engine".to_string(), serde_json::json!(v));
}
if let Some(v) = ¶ms.escalate {
body.insert("escalate".to_string(), serde_json::json!(v));
}
if let Some(v) = ¶ms.format {
body.insert("format".to_string(), serde_json::json!(v));
}
if let Some(v) = ¶ms.js_scenario {
body.insert("js_scenario".to_string(), serde_json::json!(v));
}
if let Some(v) = ¶ms.max_cost {
body.insert("max_cost".to_string(), serde_json::json!(v));
}
if let Some(v) = ¶ms.render_js {
body.insert("render_js".to_string(), serde_json::json!(v));
}
if let Some(v) = ¶ms.retry_count {
body.insert("retry_count".to_string(), serde_json::json!(v));
}
if let Some(v) = ¶ms.retry_on_block {
body.insert("retry_on_block".to_string(), serde_json::json!(v));
}
if let Some(v) = ¶ms.screenshot {
body.insert("screenshot".to_string(), serde_json::json!(v));
}
if let Some(v) = ¶ms.session_id {
body.insert("session_id".to_string(), serde_json::json!(v));
}
if let Some(v) = ¶ms.url {
body.insert("url".to_string(), serde_json::json!(v));
}
if let Some(v) = ¶ms.video {
body.insert("video".to_string(), serde_json::json!(v));
}
if let Some(v) = ¶ms.wait_after_load {
body.insert("wait_after_load".to_string(), serde_json::json!(v));
}
if let Some(v) = ¶ms.wait_for {
body.insert("wait_for".to_string(), serde_json::json!(v));
}
if let Some(v) = ¶ms.wait_timeout {
body.insert("wait_timeout".to_string(), serde_json::json!(v));
}
let body = if body.is_empty() {
None
} else {
Some(Value::Object(body))
};
self.client.send(Method::POST, &path, &query, body).await
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct DetectProtectionResponse {
pub antibot_systems: Vec<Value>,
#[serde(default, deserialize_with = "crate::core::flex::opt_string")]
pub blocking_type: Option<String>,
pub captcha_systems: Vec<Value>,
#[serde(default, deserialize_with = "crate::core::flex::opt_i64")]
pub credits_used: Option<i64>,
#[serde(default, deserialize_with = "crate::core::flex::opt_i64")]
pub duration_ms: Option<i64>,
#[serde(default, deserialize_with = "crate::core::flex::opt_bool")]
pub is_blocked: Option<bool>,
#[serde(default, deserialize_with = "crate::core::flex::opt_string")]
pub recommendation: Option<String>,
#[serde(default, deserialize_with = "crate::core::flex::opt_string")]
pub url: Option<String>,
#[serde(flatten)]
pub extra: HashMap<String, Value>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[non_exhaustive]
pub enum ScrapeUrlEngine {
#[serde(rename = "auto")]
Auto,
#[serde(rename = "browser")]
Browser,
}
impl std::fmt::Display for ScrapeUrlEngine {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(match self {
ScrapeUrlEngine::Auto => "auto",
ScrapeUrlEngine::Browser => "browser",
})
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[non_exhaustive]
pub enum ScrapeUrlFormat {
#[serde(rename = "html")]
Html,
#[serde(rename = "markdown")]
Markdown,
#[serde(rename = "text")]
Text,
}
impl std::fmt::Display for ScrapeUrlFormat {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(match self {
ScrapeUrlFormat::Html => "html",
ScrapeUrlFormat::Markdown => "markdown",
ScrapeUrlFormat::Text => "text",
})
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct ScrapeUrlResponse {
#[serde(default, deserialize_with = "crate::core::flex::opt_string")]
pub ai_error: Option<String>,
pub ai_extraction: Option<Value>,
#[serde(default, deserialize_with = "crate::core::flex::opt_string")]
pub ai_model: Option<String>,
#[serde(default, deserialize_with = "crate::core::flex::opt_bool")]
pub anti_bot_solved: Option<bool>,
pub antibot_systems: Vec<Value>,
pub blocking_details: Option<HashMap<String, Value>>,
#[serde(default, deserialize_with = "crate::core::flex::opt_bool")]
pub blocking_detected: Option<bool>,
pub captcha_systems: Vec<Value>,
#[serde(default, deserialize_with = "crate::core::flex::opt_string")]
pub content: Option<String>,
#[serde(default, deserialize_with = "crate::core::flex::opt_i64")]
pub content_length: Option<i64>,
#[serde(default, deserialize_with = "crate::core::flex::opt_i64")]
pub credits_used: Option<i64>,
#[serde(default, deserialize_with = "crate::core::flex::opt_i64")]
pub duration_ms: Option<i64>,
#[serde(default, deserialize_with = "crate::core::flex::opt_string")]
pub engine_used: Option<String>,
#[serde(default, deserialize_with = "crate::core::flex::opt_string")]
pub format: Option<String>,
pub headers: HashMap<String, Value>,
#[serde(default, deserialize_with = "crate::core::flex::opt_i64")]
pub retries_used: Option<i64>,
#[serde(default, deserialize_with = "crate::core::flex::opt_string")]
pub screenshot_url: Option<String>,
#[serde(default, deserialize_with = "crate::core::flex::opt_string")]
pub solver_used: Option<String>,
#[serde(default, deserialize_with = "crate::core::flex::opt_i64")]
pub status_code: Option<i64>,
#[serde(default, deserialize_with = "crate::core::flex::opt_bool")]
pub success: Option<bool>,
#[serde(default, deserialize_with = "crate::core::flex::opt_string")]
pub url: Option<String>,
#[serde(default, deserialize_with = "crate::core::flex::opt_string")]
pub video_url: Option<String>,
#[serde(flatten)]
pub extra: HashMap<String, Value>,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct DetectProtectionParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub country: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub timeout: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub url: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct ScrapeUrlParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub ai_extract: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ai_prompt: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub anti_bot: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub country: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub custom_headers: Option<HashMap<String, Value>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub engine: Option<ScrapeUrlEngine>,
#[serde(skip_serializing_if = "Option::is_none")]
pub escalate: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub format: Option<ScrapeUrlFormat>,
#[serde(skip_serializing_if = "Option::is_none")]
pub js_scenario: Option<Vec<HashMap<String, Value>>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_cost: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub render_js: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub retry_count: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub retry_on_block: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub screenshot: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub session_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub video: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub wait_after_load: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub wait_for: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub wait_timeout: Option<i64>,
}