Получите эмодзи кота с помощью Rust

задняя часть Rust

Соси кошек вместе с кодом! Эта статья участвует【Эссе "Мяу Звезды"】.

использоватьRustПолучите милые кошачьи мемы.

требуемые зависимости

Зависимости, используемые в этой статье,hyper,hyper-tls,scraperа такжеtokio

  • hyper: HTTPБиблиотека низкоуровневой реализации
  • hyper-tls: HTTPSБиблиотека реализации
  • scraper: разборhtmlбиблиотека
  • tokio: асинхронная среда выполнения для языка программирования Rust, предоставляющая асинхронную управляемую событиями платформу для создания быстрых, надежных и легких веб-приложений.

Если целевой сайт неHTTPSтип, вы можетеhyper-tlsполагаться. Используется при создании клиентаClient::new()Только что

шаг

  1. Создать проект

запустить в командном окнеcargo new 项目名команда для созданияrustпроект

  1. добавить зависимости

существует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"]}

  1. Проанализируйте целевой сайт

Откройте веб-сайт смайликов, чтобы найти кошек, и нажмите F12, чтобы проанализировать структуру страницы. Используйте кнопку позиционирования, чтобы найти элемент эмодзи по желанию, а левая кнопка отвечает за положение элемента в отображаемых параметрах.选择器 image.png

Вставьте скопированный селектор в текст следующим образом:#post_container > li:nth-child(2) > div.thumbnail > a > imgВ сочетании с анализом элементов страницы мы видим, что использование селекторовdiv.thumbnail > a > imgПолучите все элементы эмодзи

  1. построить и запустить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?;
  1. использовать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());
  1. использоватьCSS选择器Найдите нужный элемент
let selector = Selector::parse("div.thumbnail > a > img").unwrap();

// 循环处理选择出来的img标签
for element in document.select(&selector) {
}
  1. получить элементsrcа такжеaltАтрибуты
  • src: сетевой адрес эмодзи
  • alt: используется для переименования эмодзи
// 获取img标签的src属性
let src = element.value().attr("src").unwrap();
let alt = element.value().attr("alt").unwrap().to_string();
  1. Создайте каталог хранения и создайте имя смайлика.
/**
 * 根据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;
}
  1. Получите смайлики и сохраните их локально

запрос выше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;
}

текущий результат

image.png