Rust Scraper 从一段代码开始看起 fn main() { let response = reqwest::blocking::get( "https://meitulu.me/item/4756.html" ) .unwrap() .text() .unwrap(); let document = scraper::Html::parse_document(&response); let image_selector = scraper::Selector::parse("div.mb-4.container-inner-fix-m img").unwrap(); let images = document.select(&image_selector); images.for_each(|x| println!("{:?}", x.value().attr("src"))); } 取得 html 文本 获取 document 对象 设置 selector 使用 document 解析 selector , 得到 ElementRef 结构体 对 ElementRef 进行操作 其中 document.select 返回一个数组 ElementRef ElementRef 又一个 value 方法 pub fn value(&self) -> &'a Element 而 Element 又是 pub struct Element { pub name: QualName, pub id: Option<LocalName>, pub classes: HashSet<LocalName>, pub attrs: Attributes, } 他有方法 pub fn attr(&self, attr: &str) -> Option<&str> 可以获取节点的属性值 当然,你如果想获取节点内部的文字信息,可以对 ElementRef 使用 pub fn inner_html(&self) -> String 美女爬虫例子 use std::{fs::File, io::Write}; use std::path::{Path, PathBuf}; use url::Url; const BASE_IMAGE_URL: &str = "https://meitulu.
Serde Json 添加依赖 cargo add serde --features derive cargo add serde_json cargo add serde_derive 结构体的序列化与反序列化 use serde::{Serialize, Deserialize}; #[derive(Serialize, Deserialize, Debug)] struct Point { x: i32, y: i32, } fn main() { let point = Point {x: 1, y: 2}; let json: String = serde_json::to_string(&point).unwrap(); println!("{}", json); let point: Point = serde_json::from_str(&json).unwrap(); println!("{:#?}", point); } 枚举的序列化与反序列化 第一种枚举类型 参照结构体的序列化和反序列化,如果对一个枚举进行序列化,我们发现 use serde::{Serialize, Deserialize}; #[derive(Debug, Serialize, Deserialize)] enum Week { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday, } fn main() { let json: String = serde_json::to_string(&Week::Friday).
添加参数 Basic 以 myapp run app --release --message hello 为例 这里的参数分为几种 run 子命令 app 固定位置参数 --release flag 参数 --message hello 命名选项参数 子命令 use clap::{Parser, Subcommand}; #[derive(Parser)] #[command(author, version, about, long_about = None)] struct Cli { #[command(subcommand)] command: Commands } #[derive(Subcommand)] enum Commands { Add { name: Option<String> } } fn main() { let cli = Cli::parse(); match &cli.command { Commands::Add {name} => { println!("myapp add was used, name is: {:?}", name) } } } 在结构中使用 #[command(subcommand)] 表示以下结构是一个子命令 用 #[derive(Subcommand)] 来声明一个子命令结构 调用的时候,使用 myapp add hello 即可 固定位置参数 use clap::Parser; #[derive(Debug, Parser)] struct Cli { a: u32, b: u32, c: u32, name: String } fn main() { let cli = Cli::parse(); println!
程序介绍 这次我打算把一个 select 多路复用的程序改成多线程版本和异步版本的,他的工作流程如下 从 stdin 读取数据,处理数据 从 socket 读取数据,处理数据 而多线程和异步版本的工作流程则是 创建数据通道 channel 创建一个 线程/Future, 从 stdin 读取数据,将数据写入 channel 创建一个 线程/Future, 从 socket 读取数据,将数据写入 channel 创建一个 线程/Future, 从 channel 读取数据,处理数据 我们马上来做一下看吧 多线程程序 从 socket 读取数据的线程 let thread1 = thread::spawn(move || { loop { let (mut stream, _) = server.accept().unwrap(); let mut received = String::new(); if let Err(_) = stream.read_to_string(&mut received) { eprintln!("recv error occur"); } if let Err(e) = sender1.send(received) { eprintln!
共享单车 说明 这次的文章参考自 https://zhuanlan.zhihu.com/p/36776526 提出问题 某城市中共享单车出租的需求量如何 消费者的消费习惯 影响租车人数的因素 理解数据 导入数据 origindata = CSV.read("data/bike-sharing/train.csv", DataFrame) 查看数据集信息 describe(origindata) schema(data) 数据清洗 通过上面的数据查看,发现没有缺失值 数据类型转换 我们把 datetime 转换一下,转为 year month weekday day hour datetimes = map(x -> DateTime(x, "yyyy-mm-dd HH:MM:SS"), dataframe[!, :datetime]) years = map(year, datetimes) months = map(month, datetimes) days = map(day, datetimes) weekdays = map(dayofweek, datetimes) hours = map(hour, datetimes) dataframe[!, :year] = years dataframe[!, :month] = months dataframe[!, :weekday] = weekdays dataframe[!, :day] = days dataframe[!
电信用户流失分析 说明 这次文章的参考来自 https://zhuanlan.zhihu.com/p/68397317 提出问题 关于用户留存有这样一个观点,如果将用户流失率降低5%,公司利润将提升25%-85% 如今高居不下的获客成本让电信运营商遭遇“天花板”,甚至陷入获客难的窘境 随着市场饱和度上升,电信运营商亟待解决增加用户黏性,延长用户生命周期的问题 因此,电信用户流失分析与预测至关重要。 数据集来自 kaggle 理解数据 字段名 数据类型 字段描述 customerID String 顾客ID gender String 客户性别 SeniorCitizen Integer 客户是否为老年人 Partner String 客户是否有合作伙伴 Dependents String 客户是否有家属 tenure Integer 客户在公司停留的月数 PhoneService String 客户是否有电话服务 MultipleLines String 客户是否有多条路线 InternetService String 客户的互联网服务提供商 OnlineSecurity String 客户是否具有在线安全性 OnlineBackup String 客户是否有在线备份 DeviceProtection String 客户是否有设备保护 TechSupport String 客户是否有技术支持 StreamingTV String 客户是否有流媒体电视 StreamingMovies String 客户是否与流媒体电影 Contract String 客户的合同期限 PaperlessBilling String 客户是否有无纸化账单 PaymentMethod String 客户的支付方式 MonthlyCharges Integer 每月向客户收取的金额 TotalCharges Integer 向客户收取的总金额 Churn String 客户是否流失 数据清洗 首先导入数据 origindata = CSV.