如何提取" href"来自带有select.rs?

时间:2018-02-27 13:41:04

标签: http rust

我正在尝试编写一个非常基本的爬虫。收到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的工作原理。

1 个答案:

答案 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);
    }
}