我正在用Rust 2018 Stable和Actix-Web编写Web服务。使用Reqwest,我正在从一个路由处理程序函数中向不同的站点发出HTTP请求。简单地看起来像这样
extern crate reqwest;
use actix_web;
use reqwest::Url;
pub fn testing(req: actix_web::HttpRequest) -> actix_web::Result<actix_web::HttpResponse> {
println!(">>> testing request begin");
let url = Url::parse("https://example.com/").unwrap();
println!(">>> testing url built");
let req = reqwest::Client::new().post(url);
println!(">>> testing req prepared");
let res_struct = req.send();
println!(">>> testing res_struct received");
let res = res_struct.unwrap();
println!(">>> testing res unwrapped");
Ok(format!("done.").into())
}
Run Code Online (Sandbox Code Playgroud)
那是行不通的,并且我收到以下错误消息(尽管仅调用了一次函数,但该错误被打印了8次,“ worker:1”至“ worker:8”):
thread 'actix-rt:worker:1' panicked at 'called `Result::unwrap()`
on an `Err` value: Error(BlockingClientInFutureContext,
"https://www.example.com/")', src/libcore/result.rs:999:5
Panic in Arbiter thread, shutting down system. …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 reqwest 执行 HTTP GET 请求并将响应正文打印到 STDOUT。这适用于大多数网站,但它会为 amazon.com 返回奇怪的二进制输出:
#[tokio::main]
async fn main() {
run().await;
}
async fn run() {
let url = "https://www.amazon.com/PNY-GeForce-Gaming-Overclocked-Graphics/dp/B07GJ7TV8L/";
let resp = reqwest::get(url).await.unwrap();
let text = resp.text().await.unwrap();
println!("{}", text);
}
Run Code Online (Sandbox Code Playgroud)
为什么会resp.text().await.unwrap()返回二进制数据以及如何从中获取正常的HTTP正文?
curl 返回我期望的 HTML:
#[tokio::main]
async fn main() {
run().await;
}
async fn run() {
let url = "https://www.amazon.com/PNY-GeForce-Gaming-Overclocked-Graphics/dp/B07GJ7TV8L/";
let resp = reqwest::get(url).await.unwrap();
let text = resp.text().await.unwrap();
println!("{}", text);
}
Run Code Online (Sandbox Code Playgroud) 我正在学习 Rust,特别是并行的多线程和异步请求。
我阅读了文档,但仍然不明白我在哪里犯了错误。我想我知道在哪里,但不知道如何解决它。
主程序.rs
use std::thread;
struct Request {
url: String,
}
impl Request {
fn new(name: &str) -> Request {
Request {
url: name.to_string(),
}
}
async fn call(&self, x: &str) -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::get(x).await;
Ok(())
}
}
#[tokio::main]
async fn main() {
let requests = vec![
Request::new("https://www.google.com/"),
Request::new("https://www.google.com/"),
];
let handles: Vec<_> = requests
.into_iter()
.map(|request| {
thread::spawn(move || async {
request.call(&request.url).await;
})
})
.collect();
for y in handles {
println!("{:?}", y);
} …Run Code Online (Sandbox Code Playgroud) 我正在尝试解析来自 GET 请求的响应,但输出似乎是随机字节。
此问题仅在我尝试此网站 ( https://api.color.pizza/v1/123123 )时发生,并且在尝试其他网站时响应符合预期。
在浏览器中测试,我知道正确的响应,并且在比较正确响应的字节(存储在变量中k)和来自 reqwest 的响应时,字节完全不同。
重现错误的代码如下:
fn main() -> Result<(), Box<dyn std::error::Error>> {
//Expected output
let k = r##"{"colors":[{"hex":"#123120","name":"Méi H?i Coal","rgb":{"r":18,"g":49,"b":32},"requestedHex":"#123123","luminance":29.48870965301805,"distance":3}]}"##;
let request_url = "https://api.color.pizza/v1/123123";
let resp = reqwest::blocking::get(request_url)?.text()?;
println!("{}", resp);
let r1 = resp.into_bytes();
let r2 = String::from(k).into_bytes();
assert_eq!(&r1[..], &r2[..]);
Ok(())
}
Run Code Online (Sandbox Code Playgroud)
输出是:
fn main() -> Result<(), Box<dyn std::error::Error>> {
//Expected output
let k = r##"{"colors":[{"hex":"#123120","name":"Méi H?i Coal","rgb":{"r":18,"g":49,"b":32},"requestedHex":"#123123","luminance":29.48870965301805,"distance":3}]}"##;
let request_url = "https://api.color.pizza/v1/123123";
let resp = reqwest::blocking::get(request_url)?.text()?;
println!("{}", resp);
let r1 = resp.into_bytes(); …Run Code Online (Sandbox Code Playgroud) reqwest v0.9.18的文档显示了以下发布文件的示例:
let file = fs::File::open("from_a_file.txt")?;
let client = reqwest::Client::new();
let res = client.post("http://httpbin.org/post")
.body(file)
.send()?;
Run Code Online (Sandbox Code Playgroud)
reqwest v0.11的最新文档不再包含此示例,并且在调用时尝试构建它失败并出现以下错误body():
the trait `From<std::fs::File>` is not implemented for `Body`
Run Code Online (Sandbox Code Playgroud)
发送文件的更新方法是什么?
我正在使用 reqwest,并尝试每 97 毫秒发送一个请求。但是,我不想等待最后一个请求发生或读取它。
我只想要一个每 97 毫秒发送一次的请求,并始终将输出发送到标准输出。
我的(当前)代码是这样的:(keys是一个带有 api 键的数组)
loop {
for i in keys.iter() {
let url = format!("https://api.[insertsite].com/blahblah&apiKey={}", i);
let res = client
.get(url)
.send()
.await?
.text()
.await?;
sleep(Duration::from_millis(97)).await;
println!("{:?}", res);
}
}
Run Code Online (Sandbox Code Playgroud)
如果我删除等待,编译器会告诉我error[E0599]: no method named `text` found for opaque type `impl std::future::Future` in the current scope。
TL;DR:我想每 97 毫秒发送一次 get 请求,无论有任何响应。如果/当有一个响应管道响应标准输出。
编辑:
我尝试使用线程,但我真的不知道如何使用。这是我想出的:
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let keys = ["key", "key", "key"];
let client = …Run Code Online (Sandbox Code Playgroud) 在过去的几天里,我通过使用 reqwest crate 在 Rust 中构建一个简单的 CL 下载管理器来处理 HTTP 的东西,一直在搞乱 HTTP。我对协议的工作原理有了基本的了解 - 下载文件时要查找哪些标头,如何验证请求是否有效等 - 但我无法找到有关实际字节在何处的答案存储 HTTP 响应的主体。
例如,使用 reqwest 发送请求并获得响应所需的时间很少,因此我认为在此阶段无法进行下载。实际上需要时间的是从正文中读取字节。但是这个身体肯定不能存储在 RAM 中,因为下载一个大文件会使内存使用量猛增。我意识到这些数据的存储位置在不同的 HTTP 框架中可能会有所不同,但我想我所追求的是对不使用浏览器下载文件时大型 HTTP 响应主体的存储位置的更一般性解释。
当我运行这个时,我收到一个错误:
fn main() {
let client = reqwest::Client::new();
}
Run Code Online (Sandbox Code Playgroud)
fn main() {
let client = reqwest::Client::new();
}
Run Code Online (Sandbox Code Playgroud)
我也尝试过使用构建器,但错误仍然存在。
fn main() {
let mut client = reqwest::Client::builder(); // Panics here
match client.build() {
Err(e) => {println!("{:?}", e);}
_ => {}
}
}
Run Code Online (Sandbox Code Playgroud)
这是此代码的完整堆栈回溯。
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', libcore/option.rs:345:21
Run Code Online (Sandbox Code Playgroud) 我正在使用 Reqwest 来调用一些 API。我想要一个通用函数来解析响应,如下所示:
async fn response_to_result(response: &Response) -> anyhow::Result<()> {
let status = response.status().as_u16();
let response_message = response.text().await?; // Move here because of response.text()
return if status == 200 {
Ok(())
} else {
Err(anyhow::anyhow!(response_message))
};
}
Run Code Online (Sandbox Code Playgroud)
这是我得到的错误:
move occurs because `*response` has type `reqwest::Response`, which does not implement the `Copy` trait
Run Code Online (Sandbox Code Playgroud)
移动通过调用response.text()(方法定义pub async fn text(self) -> crate::Result<String>:)发生。通常使用参数我们可以通过引用传递,但是使用方法我不知道。有人有解决方案吗?
如何在某些网站上检索图像并将其正确使用Reqwest保存到本地?我尝试使用.text()并且图像损坏。
Error interpreting JPEG image file (Not a JPEG file: starts with 0xef 0xbf)
Run Code Online (Sandbox Code Playgroud)
我尝试过的代码
extern crate reqwest;
use std::error::Error;
use std::fs::File;
use std::io::prelude::*;
use std::path::Path;
fn main() {
let mut image_file = reqwest::Client::new()
.get("https://images.pexels.com/photos/2124773/pexels-photo-2124773.jpeg")
.send()
.unwrap()
.text()
.unwrap();
let path = Path::new("tmp/img_test.jpeg");
let display = path.display();
let mut file = match File::create(&path) {
Err(why) => panic!("couldn't create {}: {}", display, why.description()),
Ok(file) => file,
};
match file.write_all(image_file.as_bytes()) {
Err(why) => panic!("couldn't write to {}: {}", display, why.description()), …Run Code Online (Sandbox Code Playgroud) 我对 Rust 很陌生,我想编写一个脚本来抓取页面并从中提取所有带有标题的链接。我什至没有提出 get 请求。:(
fn main() {
println!("Started!");
let body = reqwest::get("https://news.ycombinator.com")
.await?
.text()
.await?;
println!("body = {:?}", body);
}
Run Code Online (Sandbox Code Playgroud)
我显然没有返回任何东西但是我对语法感到困惑有人可以解释吗?运营商,并帮助我解决这个问题。