对于百度查询接口模拟提交后结果的过滤

上篇博客有说道如何利用HtmiUnit进行模拟百度查询接口的模拟填充和提交,接下来说下如何对查询结果进行简单的过滤,提取目标网址,这里说的主要是提取目标查询关键字所对应的网址,比如查询“暨南大学”,我希望放回的是暨南大学的官网,查询“暨南大学图书馆”,返回的就是暨南大学图书馆的网址。所以目标的查询结果只需要返回最符合的一个结果,这是目的,了解了目的后说下代码。代码在上篇博客的基础上添加如下函数即可实现。

首先通过观察查询结果的HTML代码我们可以发现,查询结果一般显示10条相关结果,且他们的ID都是从[1,10]的整数,所以这样我们可以我们接下来只对这些ID号的代码进行解析,这样从某方面减小了我们解析源代码的效率,只解析局部的一小块代码。


对于查询结果分析,首先我们定义了一些敏感词,因为要获取目标对应的网址,那么这时候目标链接就不可能是百科、地图之类的相关链接,所以我们首先先排除掉关键链接字中含有敏感词的链接,剩下可疑的目标,这样有进一步减小了我们的搜索范围,也在提高程序的处理效率。


剩下的可疑目标也要进一步来分析,对于目标关键字所对应的实体,我们默认为被百度认证为官网的网址就是可信度最高的,这种情况下我们可以直接返回目标网址,非这种情况下我们要进行与目标关键字有最大相似度的链接作为候选。所以以下代码会有一部分是进行最大相似度匹配的部分countSamBalance,现在写的这种相似度是最简单的相似度计算方法,如果需要查询结果更加准确,可以改进这个算法。

findCandidateNode主要是对候选的目标进行源码分析,获取所需要最重要的那部分源码而设置的。因为我们定位的子元素是一个div块,里面含有很多杂质,不是需要的,是百度提供的关于目标结果的一个描述等内容。

String filterPage(String kw){
HtmlPage page = getPageOfSearch(kw);//获取查询结果页面
TreeMap<String, String> candidate = new TreeMap<String, String>();
for (int i = 1; i <= 10; i++) {
//HtmlDivision
DomElement tempH3 = page.getHtmlElementById(i+"");//定位到每一个目标块,id为1,2,3...10
DomNode node = findCandidateNode(tempH3,null);
if(node != null){
if(!isContainKeyWord(node.asText())){//首先判断目标块的<h3>节点里是否包含敏感词
HtmlAnchor nodeA = (HtmlAnchor) node.getFirstChild();
candidate.put(node.asText(), nodeA.getAttribute("href"));
}
}
}
Set<String> kwSet = candidate.keySet();
Map<String, Double> sambalance = new TreeMap<String, Double>();
for(String str:kwSet){
if(str.contains("官网"))
return candidate.get(str);
else{
sambalance.put(str, countSamBalance(kw, str));
}
}
System.out.println(sambalance);
if(kw != null){
return candidate.get(biggestSamBalance(sambalance));
}
return null;
}
DomNode findCandidateNode(DomNode dom,String strs){
DomNodeList<DomNode> childNode1s = dom.getChildNodes();
DomNode aimNode = null;
//System.out.println(childNode1s.size());
for (int j = 0; j < childNode1s.size(); j++) {//找到第一个包含目标的子节点
if(!childNode1s.get(j).asText().equals("") || childNode1s.get(j).asText().length()>0){//子节点必须包含文本,防止
<style>等的出现
if(strs==null){
strs = childNode1s.get(j).asText();
}

}else{
continue;
}

if((childNode1s.get(j).asText().equals(strs) || childNode1s.get(j).asText().length()>0) && childNode1s.get(j).asXml().startsWith("<")){

aimNode = childNode1s.get(j);
break;
}else{
if(aimNode == null){
while(!dom.asXml().contains("href")){
dom = dom.getParentNode();
}
return dom.getParentNode();
}
}
}
if(aimNode!=null)
aimNode = findCandidateNode(aimNode,strs);

return aimNode;
}
String biggestSamBalance(Map<String, Double> sambalance){
String aims = null;
double sbalance = 0.00;
Set<String> kwSet = sambalance.keySet();
for(String str:kwSet){
if(sbalance < sambalance.get(str)){
aims = str;
sbalance = sambalance.get(str);
}
}
return aims;
}
double countSamBalance(String kw, String objects){
double counter = 0.0;
for (int i = 0; i < kw.length(); i++) {
String childStr = kw.substring(i, i+1);
if(objects.contains(childStr))
counter++;
}
return (counter/objects.length());
}
//判断目标块里是否包含敏感词,如果有说明目标块并不是所需要的,可以忽略
boolean isContainKeyWord(String name){
String []keyWord = {"百度","百度百科","新闻","百度知道","百度地图","博客","文库"};
for (int i = 0; i < keyWord.length; i++) {
if(name.contains(keyWord[i])){
return true;
}
}
return false;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值