2021-11-07

本文使用到的依赖有hyper、hyper-tls、scraper和tokio

hyper: HTTP底层实现库
hyper-tls: HTTPS实现库
scraper: 解析html库
tokio: Rust编程语言的异步运行时,提供异步事件驱动平台,构建快速,可靠和轻量级网络应用
如果目标网站不是HTTPS类型的话,可以不用hyper-tls依赖。创建client的时候使用Client::new()即可

步骤
创建项目
在命令窗口中运行cargo new 项目名命令创建一个rust项目

加入依赖
在Cargo.toml文件中加入上面所说的依赖。Cargo.toml如下:

[package]
edition = “2021”
name = “cat”
version = “0.1.0”

See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
hyper = {version = “0.14”, features = [“full”]}
hyper-tls = “0.5.0”
scraper = “0.12.0”
tokio = {version = “1”, features = [“full”]}

复制代码
分析目标网站
打开表情包网站搜索猫咪,按F12分析页面结构。使用定位按钮随便定位一张表情包元素,左键在出现的选项中负责该元素的选择器 

将复制的选择器粘贴在文本中,如下: #post_container > li:nth-child(2) > div.thumbnail > a > img 结合页面元素分析可知,使用选择器div.thumbnail > a > img可以获得所有的表情包元素

构造并发起http/https请求, 获取页面数据
// 构建请求客户端
let https = HttpsConnector::new();
let client = Client::builder().build::<_, hyper::Body>(https);

let url = “http://www.*********.com/?s=%E7%8C%AB%E5%92%AA”;
// 发起请求获取网页数据,
let response = client.get(url.parse()?).await?;
复制代码
使用scraper解析响应数据
// 获取响应数据
let bytes = body::to_bytes(response.into_body()).await?;
// 解析HTML
let document = Html::parse_document(String::from_utf8(bytes.to_vec()).unwrap().as_ref());
复制代码
使用CSS选择器找出需要的元素
let selector = Selector::parse(“div.thumbnail > a > img”).unwrap();

// 循环处理选择出来的img标签
for element in document.select(&selector) {
}
复制代码
获取元素的src和alt属性
src:表情包的网络地址
alt:用于给表情包重命名
// 获取img标签的src属性
let src = element.value().attr(“src”).unwrap();
let alt = element.value().attr(“alt”).unwrap().to_string();
复制代码
创建存储目录及构建表情包的名称
/**

  • 根据img标签的alt属性,拼接文件保存的路径

*/
fn get_file_name(alt: &String) -> String {
let mut tmp_dir = “E:\img\”.to_string();

// 如果该目标不存在则创建
fs::create_dir_all(&tmp_dir).unwrap();

let names: Vec<_> = alt.split("[").collect();
let name = names.first().unwrap();
let name = name.trim();
let name = name.replace("?", "");
tmp_dir += &name;
tmp_dir += &".gif";

return tmp_dir;

}
复制代码
获取表情包并保存到本地
请求上面src属性获取的地址,并使用fs::write方法将表情包保存到本地

// 请求表情包的网络地址,获取表情包文件
let response = client.get(src.parse()?).await?;
let body = hyper::body::to_bytes(response).await?;

// 将文件写入本地磁盘
fs::write(&tmp_dir, body.iter())?;
复制代码
完整代码
use hyper::body;
use hyper::Client;
use hyper_tls::HttpsConnector;
use scraper::Html;
use scraper::Selector;
use std::fs;

#[tokio::main(flavor = “current_thread”)]
async fn main() -> Result<(), Box> {
// 构建请求客户端
let https = HttpsConnector::new();
let client = Client::builder().build::<_, hyper::Body>(https);

let url = "http://www.*********.com/?s=%E7%8C%AB%E5%92%AA";
// 发起请求获取网页数据,
let response = client.get(url.parse()?).await?;

if res.status() != 200 {
    panic!("请求失败");
}

// 获取响应数据
let bytes = body::to_bytes(res.into_body()).await?;
// 解析HTML
let document = Html::parse_document(String::from_utf8(bytes.to_vec()).unwrap().as_ref());
let selector = Selector::parse("div.thumbnail > a > img").unwrap();

// 循环处理选择出来的img标签
for element in document.select(&selector) {
    println!("{:?}", element.value());

    // 获取img标签的src属性
    let src = element.value().attr("src").unwrap();
    let alt = element.value().attr("alt").unwrap().to_string();

    // 根据img标签的alt属性,拼接文件保存的路径
    let tmp_dir = get_file_name(&alt);
    println!("path: {}", tmp_dir);

    // 请求表情包的网络地址,获取表情包文件
    let response = client.get(src.parse()?).await?;
    let body = hyper::body::to_bytes(response).await?;

    // 将文件写入本地磁盘
    fs::write(&tmp_dir, body.iter())?;
}

Ok(())

}

/**

  • 根据img标签的alt属性,拼接文件保存的路径

*/
fn get_file_name(alt: &String) -> String {
let mut tmp_dir = “E:\img\”.to_string();
// 如果该目标不存在则创建
fs::create_dir_all(&tmp_dir).unwrap();

let names: Vec<_> = alt.split("[").collect();
let name = names.first().unwrap();
let name = name.trim();
let name = name.replace("?", "");
tmp_dir += &name;
tmp_dir += &".gif";

return tmp_dir;

}
复制代码
运行效果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值