This commit is contained in:
Stefan Menner
2025-05-28 17:16:10 +02:00
parent ce3cf003ff
commit 6b4cc88efa
3 changed files with 257 additions and 37 deletions

View File

@@ -74,3 +74,115 @@ x1  →  
</strong> </strong>
x1&nbsp;&nbsp; x1&nbsp;&nbsp;
<small>( <i>"Schnelle Formation/Verdunstung"</i>,&nbsp;0,08 sek./Stück)</small> <small>( <i>"Schnelle Formation/Verdunstung"</i>,&nbsp;0,08 sek./Stück)</small>
<ul>
<li>
<span
class="resource-verarbeiteteswassermineral"
style="border: 1px solid #d3d3d3"
><span class="mw-valign-text-bottom" typeof="mw:File"
><a href="/de/wiki/Chlor" title="Chlor"
><img
src="data:image/gif;base64,R0lGODlhAQABAIABAAAAAP///yH5BAEAAAEALAAAAAABAAEAQAICTAEAOw%3D%3D"
decoding="async"
loading="lazy"
width="18"
height="18"
class="mw-file-element lazyload"
data-image-name="SUBSTANCE.WATER.2.png"
data-image-key="SUBSTANCE.WATER.2.png"
data-relevant="1"
data-src="https://static.wikia.nocookie.net/nomanssky_gamepedia/images/2/25/SUBSTANCE.WATER.2.png/revision/latest/scale-to-width-down/18?cb=20180726040634" /></a></span
></span>
<a href="/de/wiki/Chlor" title="Chlor"
><span class="itemlink ajaxttlink">Chlor</span></a
>
x1&#160;&#160;&#8594;&#160;&#160;
<span
class="resource-aquatischesmineral-extrakt"
style="border: 1px solid #d3d3d3"
><span class="mw-valign-text-bottom" typeof="mw:File"
><a href="/de/wiki/Salz" title="Salz"
><img
src="data:image/gif;base64,R0lGODlhAQABAIABAAAAAP///yH5BAEAAAEALAAAAAABAAEAQAICTAEAOw%3D%3D"
decoding="async"
loading="lazy"
width="18"
height="18"
class="mw-file-element lazyload"
data-image-name="SUBSTANCE.WATER.1.png"
data-image-key="SUBSTANCE.WATER.1.png"
data-relevant="1"
data-src="https://static.wikia.nocookie.net/nomanssky_gamepedia/images/9/9f/SUBSTANCE.WATER.1.png/revision/latest/scale-to-width-down/18?cb=20180726042119" /></a></span
></span>
<strong class="mw-selflink selflink"
><span class="itemlink ajaxttlink">Salz</span></strong
>
x2&#160;&#160;<small>(<i>"Salzproduktion"</i>,&#160;0,24 sek./Stück)</small>
</li>
<li>
<span
class="resource-substanzmithoherenergie"
style="border: 1px solid #d3d3d3"
><span class="mw-valign-text-bottom" typeof="mw:File"
><a href="/de/wiki/Diwasserstoff" title="Diwasserstoff"
><img
src="data:image/gif;base64,R0lGODlhAQABAIABAAAAAP///yH5BAEAAAEALAAAAAABAAEAQAICTAEAOw%3D%3D"
decoding="async"
loading="lazy"
width="18"
height="18"
class="mw-file-element lazyload"
data-image-name="SUBSTANCE.LAUNCHSUB.1.png"
data-image-key="SUBSTANCE.LAUNCHSUB.1.png"
data-relevant="1"
data-src="https://static.wikia.nocookie.net/nomanssky_gamepedia/images/0/03/SUBSTANCE.LAUNCHSUB.1.png/revision/latest/scale-to-width-down/18?cb=20180725071716" /></a></span
></span>
<a href="/de/wiki/Diwasserstoff" title="Diwasserstoff"
><span class="itemlink ajaxttlink">Diwasserstoff</span></a
>
x1&#160;&#160;+&#160;&#160;
<span
class="resource-konzentrierterflüssigtreibstoff"
style="border: 1px solid #d3d3d3"
><span class="mw-valign-text-bottom" typeof="mw:File"
><a href="/de/wiki/Sauerstoff" title="Sauerstoff"
><img
src="data:image/gif;base64,R0lGODlhAQABAIABAAAAAP///yH5BAEAAAEALAAAAAABAAEAQAICTAEAOw%3D%3D"
decoding="async"
loading="lazy"
width="18"
height="18"
class="mw-file-element lazyload"
data-image-name="SUBSTANCE.AIR.1.png"
data-image-key="SUBSTANCE.AIR.1.png"
data-relevant="1"
data-src="https://static.wikia.nocookie.net/nomanssky_gamepedia/images/e/ec/SUBSTANCE.AIR.1.png/revision/latest/scale-to-width-down/18?cb=20221007220715" /></a></span
></span>
<a href="/de/wiki/Sauerstoff" title="Sauerstoff"
><span class="itemlink ajaxttlink">Sauerstoff</span></a
>
x1&#160;&#160;&#8594;&#160;&#160;<span
class="resource-aquatischesmineral-extrakt"
style="border: 1px solid #d3d3d3"
><span class="mw-valign-text-bottom" typeof="mw:File"
><a href="/de/wiki/Salz" title="Salz"
><img
src="data:image/gif;base64,R0lGODlhAQABAIABAAAAAP///yH5BAEAAAEALAAAAAABAAEAQAICTAEAOw%3D%3D"
decoding="async"
loading="lazy"
width="18"
height="18"
class="mw-file-element lazyload"
data-image-name="SUBSTANCE.WATER.1.png"
data-image-key="SUBSTANCE.WATER.1.png"
data-relevant="1"
data-src="https://static.wikia.nocookie.net/nomanssky_gamepedia/images/9/9f/SUBSTANCE.WATER.1.png/revision/latest/scale-to-width-down/18?cb=20180726042119" /></a></span
></span>
<strong class="mw-selflink selflink"
><span class="itemlink ajaxttlink">Salz</span></strong
>
x1&#160;&#160;<small
>(<i>"Schnelle Formation/Verdunstung"</i>,&#160;0,08 sek./Stück)</small
>
</li>
</ul>

View File

@@ -1,7 +1,10 @@
use std::{fs::File, io::{Read}}; mod types;
use std::{fs::File, io::Read, net::Incoming, ops::Deref};
use scraper::{ElementRef, Node};
use ego_tree::NodeRef; use ego_tree::NodeRef;
use scraper::{Element, ElementRef, Node};
use types::Icon;
fn main() -> Result<(), Box<dyn std::error::Error>> { fn main() -> Result<(), Box<dyn std::error::Error>> {
env_logger::init(); env_logger::init();
@@ -10,7 +13,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
Ok(()) Ok(())
} }
fn _download_file(url: &str, _path: &str) -> Result<String, Box<dyn std::error::Error>> { fn _download_file(url: &str, _path: &str) -> Result<String, Box<dyn std::error::Error>> {
// Some simple CLI args requirements... // Some simple CLI args requirements...
@@ -22,13 +24,12 @@ fn _download_file(url: &str, _path: &str) -> Result<String, Box<dyn std::error::
// it for all requests. // it for all requests.
let res = reqwest::blocking::get(url)?; let res = reqwest::blocking::get(url)?;
let body = res.text()?; let body = res.text()?;
Ok(body) Ok(body)
} }
fn read(path: &str) -> Result<String, std::io::Error> { fn read(path: &str) -> Result<String, std::io::Error> {
let mut file = File::open(path)?; let mut file = File::open(path)?;
let mut contents = String::new(); let mut contents = String::new();
file.read_to_string(&mut contents)?; file.read_to_string(&mut contents)?;
Ok(contents) Ok(contents)
@@ -41,7 +42,7 @@ fn parse(html: &str) -> Result<bool, Box<dyn std::error::Error>> {
let selector_verwendung = scraper::Selector::parse("#Verwendung").unwrap(); let selector_verwendung = scraper::Selector::parse("#Verwendung").unwrap();
let selector_li = scraper::Selector::parse("li").unwrap(); let selector_li = scraper::Selector::parse("li").unwrap();
let elt_quelle= document.select(&selector_quelle).next(); let elt_quelle = document.select(&selector_quelle).next();
if elt_quelle.is_none() { if elt_quelle.is_none() {
eprintln!("No element found with the selector '#Quelle'"); eprintln!("No element found with the selector '#Quelle'");
@@ -55,11 +56,10 @@ fn parse(html: &str) -> Result<bool, Box<dyn std::error::Error>> {
let mut c = 0; let mut c = 0;
let mut elt_ul = None; let mut elt_ul = None;
while elt_quelle. next_sibling().is_some() { while elt_quelle.next_sibling().is_some() {
elt_quelle = elt_quelle.next_sibling().unwrap(); elt_quelle = elt_quelle.next_sibling().unwrap();
if !elt_quelle.value().is_element(){ if !elt_quelle.value().is_element() {
continue; continue;
} }
@@ -86,12 +86,11 @@ fn parse(html: &str) -> Result<bool, Box<dyn std::error::Error>> {
let elt_ul = ElementRef::wrap(elt_ul.unwrap()).unwrap(); let elt_ul = ElementRef::wrap(elt_ul.unwrap()).unwrap();
let li = elt_ul.select(&selector_li); let li = elt_ul.select(&selector_li);
for item in li for item in li {
{
parse_li_to_resource(item); parse_li_to_resource(item);
} }
let elt_verwendung= document.select(&selector_verwendung).next(); let elt_verwendung = document.select(&selector_verwendung).next();
if elt_verwendung.is_none() { if elt_verwendung.is_none() {
eprintln!("No element found with the selector '#Verwendung'"); eprintln!("No element found with the selector '#Verwendung'");
@@ -109,29 +108,97 @@ fn parse_li_to_resource(item: ElementRef<'_>) {
return; return;
} }
let mut resource_items = Vec::new(); let mut resource_items: Vec<NodeRef<'_, Node>> = Vec::new();
let selector = scraper::Selector::parse("span,a,img,small").unwrap();
let iter = item.select(&selector);
let first_child = item.first_child().unwrap(); for child in iter {
println!(
"name: {}, text: {}, text1: {}",
child.value().name(),
get_text(child.deref()),
get_text1(child.deref())
);
}
println!("======================");
}
resource_items.push(first_child); fn get_text(node: &NodeRef<'_, Node>) -> String {
if node.value().is_text() {
return node.value().as_text().unwrap().text.trim().to_string();
}
let iter = first_child.next_siblings(); if node.value().is_element() {
let mut text = String::new();
for next in iter { for child in node.children() {
if next.value().is_text() { text.push_str(&get_text(&child));
resource_items.push(next);
} }
else if next.value().is_element() {
if next.value().as_element().unwrap().name() == "span" {
parse_resource (resource_items);
resource_items = Vec::new();
}
resource_items.push(next); if !text.is_empty() {
return text;
} }
} }
println!("======================"); let next = node.next_sibling();
if !next.is_some() {
return String::new();
}
let next = next.unwrap();
if next.value().is_text() {
return next.value().as_text().unwrap().text.trim().to_string();
}
String::new()
}
fn get_text1(node: &NodeRef<'_, Node>) -> String {
if node.value().is_text() {
return node.value().as_text().unwrap().text.trim().to_string();
}
let next = node.next_sibling();
if !next.is_some() {
return String::new();
}
let next = next.unwrap();
if next.value().is_text() {
return next.value().as_text().unwrap().text.trim().to_string();
}
String::new()
}
fn add_all_children<'a>(
child: NodeRef<'a, Node>,
resource_items: &mut Vec<NodeRef<'a, Node>>,
) -> bool {
let mut result = false;
if child.value().is_text() {
resource_items.push(child);
} else if child.value().is_element() {
let selector = scraper::Selector::parse("a,img,small").unwrap();
if child.value().as_element().unwrap().name() == "span" {
result = true;
}
if child.value().as_element().unwrap().name() == "a" {
resource_items.push(child);
}
let items = ElementRef::wrap(child).unwrap().select(&selector);
for item in items {
let x = item.deref();
resource_items.push(*x);
}
}
result
} }
fn parse_resource(resource_items: Vec<NodeRef<'_, Node>>) { fn parse_resource(resource_items: Vec<NodeRef<'_, Node>>) {
@@ -140,16 +207,37 @@ fn parse_resource(resource_items: Vec<NodeRef<'_, Node>>) {
return; return;
} }
let mut url: Option<&str> = Option::None;
let mut title: Option<&str> = Option::None;
let mut icon: Option<Icon> = Option::None;
println!("Parsing resource items..."); println!("Parsing resource items...");
for item in resource_items { for item in resource_items {
if item.value().is_text() { if item.value().is_text() {
println!("Text: {}", item.value().as_text().unwrap().text.trim_ascii()); println!(
"Text: {}",
item.value().as_text().unwrap().text.trim_ascii()
);
continue; continue;
} }
println!("Resource: {:?}", item.value()); check_item(&item, &mut url, &mut title, &mut icon);
println!("Resource: {:?}", url);
} }
println!("------------------"); println!("------------------");
}
fn check_item(
item: &NodeRef<'_, Node>,
url: &mut Option<&str>,
title: &mut Option<&str>,
icon: &mut Option<Icon>,
) {
println!(
"Checking item: {} {:?}",
item.value().as_element().unwrap().name(),
item.value().as_element().unwrap().attrs
);
*url = Some("test");
} }

View File

@@ -0,0 +1,20 @@
#[derive(Debug, PartialEq, Eq)]
pub struct Icon {
pub name: String,
pub url: String,
pub width: u32,
pub height: u32,
pub content_type: String,
}
impl Clone for Icon {
fn clone(&self) -> Self {
Icon {
name: self.name.clone(),
url: self.url.clone(),
width: self.width,
height: self.height,
content_type: self.content_type.clone(),
}
}
}