【发布时间】:2018-02-28 01:54:24
【问题描述】:
我正在尝试编写一个非常基本的爬虫。收到 HTTP 响应后,我使用 select.rs crate 从正文中提取 URL 以进行进一步爬取。
如何使用“for-iteration”从作为 HTTP 响应的“正文”部分的“文档”中提取这些 URL?
extern crate hyper;
extern crate select;
extern crate xhtmlchardet;
extern crate robotparser;
extern crate url;
use std::io::Read;
use Crawler::hyper::client::Client;
use Crawler::hyper::header::Connection;
use Crawler::select::document::Document;
use Crawler::select::predicate::*;
pub fn crawl(url: &str) {
//Opens up a new HTTP client
let client = Client::new();
//Creates outgoing request
let mut res = client.get(&*url)
.header(Connection::close())
.send().unwrap();
//Reads the response
let mut body = String::new();
res.read_to_string(&mut body).unwrap();
println!("Response: {}", res.status);
println!("Headers:\n{}", res.headers);
println!("Body:\n{}", body);
let document = Document::from_str(&*body);
for node in document.find(Attr("id", "hmenus")).find(Name("a")).iter() {
println!("{} ({:?})", node.text(), node.attr("href").unwrap());
}
}
对诸如“um.ac.ir”之类的 URL 执行抓取的结果是带有正文的完整 HTTP 响应。我正在尝试从此输出中提取hrefs。
Response: 200 OK
Headers:
X-Content-Type-Options: nosniff
X-Frame-Options: sameorigin
Cache-Control: cache
Date: Tue, 27 Feb 2018 13:16:27 GMT
Vary: Accept-Encoding
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Transfer-Encoding: chunked
Pragma: no-cache
Server: GFW/2.0
Connection: close
Content-Type: text/html; charset=utf-8
Strict-Transport-Security: max-age=63072000; preload
Set-Cookie: POSTNUKESID=pnd2nuadgastqak5h6nop87c63; path=/
...
<div class="col-md-4">
<h3>سایر</h3>
<ul>
<li><a target="_blank" href="http://ftpnews.um.ac.ir/">سایت خبری ftp دانشگاه</a></li>
<li><a target="_blank" href="http://news.um.ac.ir/Topic96.html">گزینش دانشگاه </a></li>
<li><a target="_blank" href="http://herasat.um.ac.ir/index.php?lang=fa">مدیریت حراست دانشگاه </a></li>
<li><a target="_blank" href="http://mafakher.um.ac.ir/">مركز آثارمفاخر و اسناد دانشگاه</a></li>
<li><a target="_blank" href="http://intr.um.ac.ir/">مدیریت همكاری های علمی و بین المللی</a></li>
<li><a target="_blank" href="http://eva.um.ac.ir/"> مدیریت نظارت و ارزیابی دانشگاه</a></li>
<li><a target="_blank" href="http://saybanemehr.um.ac.ir/">سایت سایبان مهر</a></li>
<li><a target="_blank" href="http://faf.um.ac.ir/">بنیاد دانشگاهی فردوسی</a></li>
<li><a target="_blank" href="http://ads.um.ac.ir/">آگهي ها و تبليغات دانشگاه</a></li>
<li><a target="_blank" href="http://fumblog.um.ac.ir/">سامانه مدیریت وبلاگ</a></li>
<li><a target="_blank" href="http://basijasatid.um.ac.ir/">بسیج اساتید</a></li>
<li><a target="_blank" href="http://basij.um.ac.ir/">بسیج كاركنان</a></li>
<li><a target="_blank" href="http://nahad.um.ac.ir/">نهاد نمایندگی رهبری در دانشگاه</a></li>
</ul>
</div>
...
问题是println!("{} ({:?})", node.text(), node.attr("href").unwrap()) 没有输出任何东西,因为[...].iter() 工作不正常:
for node in document.find(Attr("id", "hmenus")).find(Name("a")).iter() {
println!("{} ({:?})", node.text(), node.attr("href").unwrap());
}
find(Attr("id", "hmenus")).find(Name("a")) 似乎不是从 HTTP 响应正文中查找“href”标签的正确方法。
我相信重写这部分应该可以解决我的代码中的问题,尽管它需要全面了解 select::document 的工作原理。
【问题讨论】:
-
您忘记说明您的代码的问题是什么。从表面上看,它似乎可行。
-
问题出在最后一部分,正如我提到的,我需要帮助编写代码的“for-iteration”部分。
-
你已经已经写过那部分了。来自您的代码:
for node in document.find(Attr("id", "hmenus")).find(Name("a")).iter()。那是一个for循环。它迭代。目前还不清楚到底是什么问题。 -
好吧,我相应地编辑了问题并在代码的“for-iteration”部分指定了问题,抱歉造成误解,希望对您有所帮助。
-
似乎 [...] 不是正确的方式 — 但是为什么它“看起来”不是正确的方式?您是否收到编译错误、运行时错误、不正确/格式错误的数据等? 我相信重写这部分应该可以解决问题——你还没有说你遇到的问题是什么是。