我正在尝试编写一个非常基本的爬虫。收到HTTP响应后,我使用select.rs包来从正文中提取网址以进一步抓取。
如何从"文档"中提取这些网址?这是"身体"使用" for-iteration"的HTTP响应的一部分
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"等网址执行抓取的结果是一个带有正文的完整HTTP响应。我试图从此输出中提取href
s。
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"))
似乎不是找到&#34; href&#34;的正确方法。来自HTTP响应正文的标记。
我认为重写此部分应该可以解决我的代码中的问题,尽管它需要全面了解select::document
的工作原理。
答案 0 :(得分:1)
我假设你从一些示例代码中复制了Attr("id", "hmenus")
。这是一个筛选谓词,它匹配包含属性id="hmenus"
的HTML节点。您的示例页面um.ac.ir不包含任何属性为id="hmenus"
的节点。如果您希望抓取工具找到所有&lt; a&gt;在页面上的节点,过滤谓词将是Name("a")
。
for node in document.find(Name("a")).iter() {
if let Some(href) = node.attr("href") {
println!("{} ({:?})", node.text().trim(), href);
}
}