分享

web信息的搜集---Page h+Page cpp<2>集

 闲来看看 2013-01-18

web信息的搜集---Page.h+Page.cpp<2>

//从网页中提取出超链接信息

bool CPage::ParseHyperLinks()

{

if(GetContentLinkInfo()==false)

return false;

if(m_sContentLinkInfo.empty())

return false;

bool bFind4SE=false;

bool bFind4History=false;

if(GetLinkInfo4SE())

if(FindRefLink4SE())

bFind4SE=true;

if(GetLinkInfo4History())

if(FindRefLink4History())

bFind4History=true;

//如果没有从网页中提取出为搜索引擎或者为历史网页存档准备的超链接则返回false

if(!bFind4SE&&!bFind4History)

return false;

return true;

}

//从网页体中提取出包含超链接信息的标识

bool CPage::GetContentLinkInfo()

{

if(m_sContent.empty())

return false;

m_sContentLinkInfo=m_sContent;

string &s=m_sContentLinkInfo;

const string delims("\t\r\n");

string::size_type pre_idx,idx=0;

//找到所有的"\t\r\n"并将'\t'替换为' ' 如果是\t\t\r\n则删除一个\t

while((idx=s.find_first_of(delims,idx))!=string::npos)

{

pre_idx=idx;

//删除从idx开始的一个字符,并用一个' '替换

s.replace(idx,1,1,' ');

idx++;

while((idx=s.find_first_of(delims,idx))!=string::npos)

{

if(idx-pre_idx==1)

s.erase(idx,1);

else

break;

}

idx--;

}

//将s中<br>标记全部替换为空格

CStrFun::ReplaceStr(s,"<br>"," ");

if(s.size()<20)

return false;

/*

例如:一个网页中有如下超链接

<a href="http://www.baidu.com/">百度</a><a href="http://www.qq.com/">QQ</a><img src="http://www."><......

我们将会提取为

m_sContentLinkInfo=href="http://www.baidu.com/">百度href="http://www.qq.com/">QQ<img src="http://www.">

*/

string::size_type idxHref=0,idxArea=0,idxImg=0;

string dest;

do

{

if(s.empty())

break;

idxHref=CStrFun::FindCase(s,"href");

idxArea=CStrFun::FindCase(s,"<area");

idxImg=CStrFun::FindCase(s,"<img");

pre_idx=idxHref>idxArea?idxArea:idxHref;

pre_idx=pre_idx>idxImg?idxImg:pre_idx;

if(pre_idx==string::npos)

break;

s=s.substr(pre_idx);

idx=s.find_first_of('<',1);

if(idx!=string::npos)

dest=dest+s.substr(0,idx);

else

break;

s=s.substr(idx);

idxHref=idxImg=idxArea=0;

}while(1);

s=dest;

/*

删除所有的'\'字符 避免出现下面的情况---注意'\'是转义字符"\\"

document.write("<a href=\"http://www.baidu.com/index.html\">百度</a>");

*/

CStrFun::EraseStr(s,"\\");

if(s.size()<20)

return false;

return true;

}

//再从m_sContentLinkInfo提取出为搜索引擎准备的超链接

bool CPage::GetLinkInfo4SE()

{

if(m_sContentLinkInfo.empty())

return false;

m_sLinkInfo4SE=m_sContentLinkInfo;

string &s=m_sLinkInfo4SE;

string::size_type pre_idx,idx,idxHref=0,idxArea=0;

string dest;

/*

例如:上面的m_sContentLinkInfo=href="http://www.baidu.com/">百度href="http://www.qq.com/">QQ<img src="http://www.">

我们这里提取出href="http://www.baidu.com/">百度href="http://www.qq.com/">QQ    过滤掉<img src="http://www.">

因为<img src="http://www.">的超链接是为历史网页存档准备的超链接

*/

do

{

if(s.empty())

break;

idxHref=CStrFun::FindCase(s,"href");

idxArea=CStrFun::FindCase(s,"<area ");

pre_idx=idxHref>idxArea?idxArea:idxHref;

if(pre_idx==string::npos)

break;

s=s.substr(pre_idx);

idx=s.find_first_of('<',1);

if(!(s.length()<4))

{

idxHref=CStrFun::FindCaseFrom(s,"href",4);

idx=idx>idxHref?idxHref:idx;

}

if(idx!=string::npos)

dest=dest+s.substr(0,idx);

else if(idx==string::npos&&pre_idx!=string::npos)

{

dest=dest+s;

break;

}

else

break;

s=s.substr(idx);

idxHref=idxArea=0;

}while(1);

s=dest;

if(s.length()<20)

return false;

CStrFun::EraseStr(s,"\"");

CStrFun::EraseStr(s,"'");

CStrFun::EraseStr(s,"&nbsp");

dest.clear();

idxHref=0;

/*

通过上面的提取我们得到href="http://www.baidu.com/">百度href="http://www.qq.com/">QQ

我们再次提取

m_sLinkInfo4SE="http://www.baidu.com/">百度"http://www.qq.com/">QQ

*/

const string delims(" #>");

do

{

if(s.empty())

break;

idxHref=CStrFun::FindCase(s,"href");

if(idxHref==string::npos)

break;

idx=s.find('=',idxHref);

if(idx==string::npos)

break;

s=s.substr(idx+1);

while(s.length()>0&&s[0]==' ')

s.erase(0,1);

if(s.length()==0)

break;

idx=s.find_first_of(delims,1);

if(idx==string::npos)

break;

dest+='"'+s.substr(0,idx);

idx=s.find('>');

if(idx==string::npos)

break;

dest+='>';

s=s.substr(idx+1);

idx=s.find('<');

if(!s.empty())

{

idxHref=CStrFun::FindCase(s,"href");

idx=idx>idxHref?idxHref:idx;

}

if(idx==string::npos)

{

dest+=s;

break;

}

dest+=s.substr(0,idx);

idxHref=0;

}while(1);

idx=0;

while((idx=dest.find("\"\"",idx))!=string::npos)

{

dest.erase(idx,1);

}

s=dest;

return s.length()<20?false:true;

}

//再从m_sContentLinkInfo提取出为历史网页存档准备的超链接

bool CPage::GetLinkInfo4History()

{

if(m_sContentLinkInfo.empty())

return false;

m_sLinkInfo4History=m_sContentLinkInfo;

string &s=this->m_sLinkInfo4History;

string::size_type pre_idx,idx,idxImg=0,idxHref=0;

string dest;

/*

例如:上面的m_sContentLinkInfo=href="http://www.baidu.com/">百度href="http://www.qq.com/">QQ<img src="http://www.">

我们这里提取出<img src="http://www.">   过滤掉href="http://www.baidu.com/">百度href="http://www.qq.com/">QQ

因为href="http://www.baidu.com/">百度href="http://www.qq.com/">QQ的超链接是为搜索引擎准备的超链接

*/

do

{

if(s.empty())

break;

idxImg=CStrFun::FindCase(s,"<img");

pre_idx=idxImg;

if(pre_idx==string::npos)

break;

s=s.substr(pre_idx);

idx=s.find_first_of('<',1);

if(!(s.length()<4))

{

idxHref=CStrFun::FindCaseFrom(s,"href",4);

idx=idx>idxHref?idxHref:idx;

}

if(idx!=string::npos)

dest+=s.substr(0,idx);

else if(idx==string::npos&&pre_idx!=string::npos)

{

dest+=s;

break;

}

else

break;

s=s.substr(idx);

idxImg=0;

}while(1);

s=dest;

if(s.length()<20)

return false;

CStrFun::EraseStr(s,"\"");

CStrFun::EraseStr(s,"'");

CStrFun::EraseStr(s,"&nbsp");

dest.clear();

idxImg=0;

/*

通过上面的提取我们得到<img src="http://www.">

    我们再次提取

    m_sLinkInfo4History="http://www.>

*/

const string delims(" #>");

string::size_type idxSrc=0;

do

{

if(s.empty())

break;

idxImg=CStrFun::FindCase(s,"img");

if(idxImg==string::npos)

break;

s=s.substr(idxImg+3);

if(s.empty())

break;

idxSrc=CStrFun::FindCase(s,"src");

if(idxSrc==string::npos)

break;

idx=s.find('=',idxSrc);

if(idx==string::npos)

break;

s=s.substr(idx+1);

while(s.length()>0&&s[0]==' ')

s.erase(0,1);

if(s.length()==0)

break;

idx=s.find_first_of(delims,1);

if(idx==string::npos)

break;

if(s.at(0)=='"')

dest+=s.substr(0,idx);

else

dest+='"'+s.substr(0,idx);

idx=s.find('>');

if(idx==string::npos)

break;

dest+='>';

s=s.substr(idx+1);

idx=s.find('<');

if(idx==string::npos)

{

dest+=s;

break;

}

dest+=s.substr(0,idx);

idxImg=0;

}while(1);

idx=0;

while((idx=dest.find("\"\""))!=string::npos)

{

dest.erase(idx,1);

}

s=dest;

return s.length()<20?false:true;

}

//判断strUrl是不是正规的url

bool CPage::NormalizeUrl(string &strUrl)

{

string::size_type idx=0;

//URL没有htp://协议名我们这里认为strUrl不是正规的URL

if(CStrFun::FindCase(strUrl,"http://")==string::npos)

return false;

    //将http://www.baidu.com转化为http://www.baidu.com/

idx=strUrl.rfind('/');

if(idx<8)

{

strUrl+="/";

return true;

}

//将"/./"-->"/"

while((idx=strUrl.find("/./"))!=string::npos)

{

if(idx!=string::npos)

strUrl.erase(idx,2);

}

//将"xxxx/../yyy"-->xxx/yyy

while((idx=strUrl.find("/../"))!=string::npos)

{

string strPre,strBuf;

strPre=strUrl.substr(0,idx);

if(strUrl.size()>idx+4)

strBuf=strUrl.substr(idx+4);

idx=strPre.rfind("/");

if(idx!=string::npos)

strPre=strPre.substr(0,idx+1);

if(strPre.length()<10)

return false;

strUrl=strPre+strBuf;

}

//最后再次检测一下URL中是否还有"http://"协议名

if(CStrFun::FindCase(strUrl,"http://")!=0)

return false;

return true;

}

/*最终得到为搜索引擎准备的超链接

  并将相对路径的URL和绝对路径的URL分别处理,同时,我们发现从一个网页中提取的超链接可以是相同的,这个时候

  我们必须去重,这个函数用map容器很好的做到了这一点

  还有一些URL不是正规的URL也要过滤

  还有一些URL是必要过滤也要过滤--通过IsFilterLink(string strUrl)实现

 */

bool CPage::FindRefLink4SE()

{

if(m_sLinkInfo4SE.empty())

return false;

char *buffer=(char *)m_sLinkInfo4SE.c_str();

int urlnum=0,len;

char *ptr;

static char buf[URL_REFERENCE_LEN];

memset(buf,0,URL_REFERENCE_LEN);

len=strlen(buffer);

if(len<8)

return false;

len=len<URL_REFERENCE_LEN-1?len:URL_REFERENCE_LEN-1;

strncpy(buf,buffer,len);

/*

例如:m_sLinkInfo4SE="http://www.baidu.com/">百度"http://www.qq.com/">QQ

我们这里提取为

http://www.baidu.com  百度

http://www.    QQ

*/

ptr=buf;

while(ptr-buf<len&&*ptr)

{

while(*ptr=='"'&&*ptr)ptr++;

if(!*ptr)

break;

this->m_RefLink4SE[urlnum].link=ptr;

while(*ptr&&*ptr!='>')

{

if(*ptr==' ')//在遇到'>'之前,出现了' '字符,我们必须将' '字符赋值为'\0'说明URL提取完了,因为URL不可能出现' '字符

*ptr='\0';

//例如: "http://www.baidu.com/" height=100 width=150>百度   出现空格说明还有其他的属性值

ptr++;

}//end while

if(!*ptr)

{

urlnum++;

break;

}//end if

if(*ptr=='>')

{

  *ptr++='\0';

  if(!*ptr)

  {

  urlnum++;

  break;

  }//end if

  if(*ptr=='"')

  m_RefLink4SE[urlnum].anchor_text=NULL;

  else

  {

  m_RefLink4SE[urlnum].anchor_text=ptr;

  while(*ptr&&*ptr!='"')ptr++;

  if(!*ptr)

  {

  urlnum++;

  break;

  }//end if

  if(*ptr=='"')

  *ptr='\0';

  }//ene if

}//end if

ptr++;

urlnum++;

if(urlnum==MAX_URL_REFERENCES)

break;

}//end while

m_nRefLink4SENum=urlnum;

typedef map<string,string>::value_type valType;

m_mapLink4SE.clear();

CUrl iUrl;

if(iUrl.ParseUrlEx(m_sUrl)==false)

{

cout<<"ParseUrlEx erro in CPage::FindRefLink4SE():"<<endl;

return false;

}

for(int i=0;i<m_nRefLink4SENum;i++)

{

string str;

string::size_type idx;

const string delims(" #");

str=m_RefLink4SE[i].link;

idx=str.find_first_of(delims,0);

if(idx!=string::npos)

str=str.substr(0,idx);

if(str.size()==0||str.size()<4||str.size()>URL_LEN-1)

continue;

string::size_type idx1;

idx1=CStrFun::FindCase(str,"http");

if(idx1!=0)//str有可能是相对路径

{

char c1=m_sUrl.at(m_sUrl.length()-1);

char c2=str.at(0);

if(c2=='/')//str一定是相对路径

{

if(iUrl.m_nPort!=80)

str="http://"+iUrl.m_sHost+":"+CStrFun::itos(iUrl.m_nPort)+str;

else

str="http://"+iUrl.m_sHost+str;

}

else if(c1!='/'&&c2!='/')

{

string::size_type idx;

idx=m_sUrl.rfind('/');

if(idx!=string::npos)

{

if(idx>6)

str=m_sUrl.substr(0,idx+1)+str;

else

str=m_sUrl+"/"+str;

}//end if

else

continue;

}

else//  c2!='/'  c1=='/';

{

if(c1=='/')

str=m_sUrl+str;

else

str=m_sUrl+"/"+str;

}//end if

}//end if

if(NormalizeUrl(str)==false)

continue;

if(IsFilterLink(str))

continue;

if(str==m_sUrl)//一个网页中提取的超链接是其本身,我就不要了,因为我们已经有了这个网页的URL了

continue;

else

{//这样做为的是给URL去重

if(m_RefLink4SE[i].anchor_text)//有URL的描述符

{

if(m_mapLink4SE.find(str)==m_mapLink4SE.end())

m_mapLink4SE.insert(valType(str,m_RefLink4SE[i].anchor_text));

}

else//没有URL的描述符---这个时候描述符为'\0'

{

if(m_mapLink4SE.find(str)==m_mapLink4SE.end())

m_mapLink4SE.insert(valType(str,"\0"));

}//end if

}//end if

}//end for

    m_nRefLink4SENum=m_mapLink4SE.size();

    return true;

}

//最终得到为历史网页存档准备的超链接

//并将相对路径的URL和绝对路径的URL分别处理,同时,我们发现从一个网页中提取的超链接可以是相同的,这个时候

//我们必须去重,这个函数用vector容器很好的做到了这一点

//还有一些URL不是正规的URL也要过滤

//还有一些URL是必要过滤也要过滤--通过IsFilterLink(string strUrl)实现

bool CPage::FindRefLink4History()

{

if(m_sLinkInfo4History.empty())

return false;

char *buffer=(char*)m_sLinkInfo4History.c_str();

int urlnum=0,len;

char *ptr ;

static char buf[URL_REFERENCE_LEN/2];

memset(buf,0,URL_REFERENCE_LEN/2);

len=strlen(buffer);

if(len<8)

return false;

len=len<URL_REFERENCE_LEN/2-1?len:URL_REFERENCE_LEN/2-1;

strncpy(buf,buffer,len);

/*

例如:m_sLinkInfo4History="http://www.">

我们这里提取为

http://www.

*/

ptr=buf;

while(ptr-buf<len &&*ptr)

{

while(*ptr=='"'&&*ptr)ptr++;

if(!*ptr)

break;

this->m_RefLink4History[urlnum].link=ptr;

while(*ptr&&*ptr!='>')

{

if(*ptr==' ')//在遇到'>'之前,出现了' '字符,我们必须将' '字符赋值为'\0'说明URL提取完了,因为URL不可能出现' '字符

*ptr='\0';

//例如: "http://www./" height=100 width=150>google   出现空格说明还有其他的属性值

ptr++;

}//end while

if(!*ptr)

{

urlnum++;

break;

}

if(*ptr=='>')

{

*ptr++='\0';

if(!*ptr)

{

urlnum++;

break;

}

if(*ptr=='"')

{

}

else

{

while(*ptr&&*ptr!='"')

ptr++;

if(!*ptr)

{

urlnum++;

break;

}

if(*ptr=='"')

*ptr='\0';

}//end if

}//end if

ptr++;

urlnum++;

if(urlnum==MAX_URL_REFERENCES/2)

break;

}//end while

this->m_nRefLink4HistoryNum = urlnum;

m_vecLink4History.clear();

    CUrl iUrl;

    if(iUrl.ParseUrlEx(m_sUrl)==false)

    {

   cout<<"ParseUrlEx error in CPage::FindRefLink4History():"<< endl;

return false;

}

for(int i=0;i<m_nRefLink4HistoryNum;i++)

{

string str;

str=m_RefLink4History[i].link;

if(str.size()==0||str.size()>URL_LEN-1||str.size()<4)

continue;

string::size_type idx1;

idx1=CStrFun::FindCase(str,"http");

if(idx1!=0)//str有可能是相对路径

{

char c1=m_sUrl.at(m_sUrl.length()-1);

char c2=str.at(0);

if(c2=='/')//str一定是相对路径

{

if(iUrl.m_nPort!=80 )

str="http://"+iUrl.m_sHost+":"+CStrFun::itos(iUrl.m_nPort)+str;

else

str="http://"+iUrl.m_sHost+str;

}

else if(c1!='/'&&c2!='/')

{

string::size_type idx;

idx=m_sUrl.rfind('/');

if(idx!=string::npos)

{

if(idx>6) // > strlen("http://..")

str=m_sUrl.substr(0,idx+1)+str;

else

str=m_sUrl+"/"+str;

}

else

{

continue;

}

}

else// c2!='/' c1=='/'

{

if(c1=='/')

str=m_sUrl+str;

else

str=m_sUrl+"/"+str;

}//end if

}//end if

if(NormalizeUrl(str)==false)

continue;

if(IsFilterLink(str))

continue;

if(str==m_sUrl)

continue;

else

{

vector<string>::iterator it;

it=find(m_vecLink4History.begin(),m_vecLink4History.end(),str);

if(it==m_vecLink4History.end())

m_vecLink4History.push_back(str);

}

}//end for

m_nRefLink4HistoryNum = m_vecLink4History.size();

return true;

}

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多