我正在尝试在Rust中构建一个基本的Web爬虫,我正在尝试移植到html5ever。截至目前,我有一个带有结构的函数,它应该返回一个Vec<String>
。它从return语句中的结构中获取此Vec
。为什么它总是返回一个空向量? (它与生命周期参数有关吗?)
fn find_urls_in_html<'a>(
original_url: &Url,
raw_html: String,
fetched_cache: &Vec<String>,
) -> Vec<String> {
#[derive(Clone)]
struct Sink<'a> {
original_url: &'a Url,
returned_vec: Vec<String>,
fetched_cache: &'a Vec<String>,
}
impl<'a> TokenSink for Sink<'a> {
type Handle = ();
fn process_token(&mut self, token: Token, _line_number: u64) -> TokenSinkResult<()> {
trace!("token {:?}", token);
match token {
TagToken(tag) => {
if tag.kind == StartTag && tag.attrs.len() != 0 {
let _attribute_name = get_attribute_for_elem(&tag.name);
if _attribute_name == None {
return TokenSinkResult::Continue;
}
let attribute_name = _attribute_name.unwrap();
for attribute in &tag.attrs {
if &attribute.name.local != attribute_name {
continue;
}
trace!("element {:?} found", tag);
add_urls_to_vec(
repair_suggested_url(
self.original_url,
(&attribute.name.local, &attribute.value),
),
&mut self.returned_vec,
&self.fetched_cache,
);
}
}
}
ParseError(error) => {
warn!("error parsing html for {}: {:?}", self.original_url, error);
}
_ => {}
}
return TokenSinkResult::Continue;
}
}
let html = Sink {
original_url: original_url,
returned_vec: Vec::new(),
fetched_cache: fetched_cache,
};
let mut byte_tendril = ByteTendril::new();
{
let tendril_push_result = byte_tendril.try_push_bytes(&raw_html.into_bytes());
if tendril_push_result.is_err() {
warn!("error pushing bytes to tendril: {:?}", tendril_push_result);
return Vec::new();
}
}
let mut queue = BufferQueue::new();
queue.push_back(byte_tendril.try_reinterpret().unwrap());
let mut tok = Tokenizer::new(html.clone(), std::default::Default::default()); // default default! default?
let feed = tok.feed(&mut queue);
return html.returned_vec;
}
输出结束时没有警告(由于此为空,由另一个功能引起的恐慌)。任何人都可以帮我弄清楚发生了什么事吗?
提前致谢。
答案 0 :(得分:1)
初始化module TestAircall
describe Aircall::Users do
def self.user_by_id
@user_by_id ||= DefaultAircall::AIRCALL.users.get_by_id(ENV['TEST_DEFAULT_USER_ID'])
end
DefaultTest::Run.('user_by_id')
end
end
时,我使用:
Tokenizer
问题在于我告诉令牌生成器使用let mut tok = Tokenizer::new(html.clone(), std::default::Default::default());
而不是html.clone()
。因此,它将html
写入克隆对象,而不是returned_vec
。更改一些内容,例如使用带有可变引用的变量,可以解决此问题。