Соси кошек вместе с кодом! Эта статья участвует【Эссе "Мяу Звезды"】.
использоватьRust
Получите милые кошачьи мемы.
требуемые зависимости
Зависимости, используемые в этой статье,hyper
,hyper-tls
,scraper
а такжеtokio
-
hyper
:HTTP
Библиотека низкоуровневой реализации -
hyper-tls
:HTTPS
Библиотека реализации -
scraper
: разборhtml
библиотека -
tokio
: асинхронная среда выполнения для языка программирования Rust, предоставляющая асинхронную управляемую событиями платформу для создания быстрых, надежных и легких веб-приложений.
Если целевой сайт не
HTTPS
тип, вы можетеhyper-tls
полагаться. Используется при создании клиента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<dyn std::error::Error>> {
// 构建请求客户端
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;
}
текущий результат