TSE代码爬取流程分析

开始是main函数,在main.cpp

如果控制台参数是1个,就进行搜索:

CSearch iSearch;
   iSearch.DoSearch();

 

如果控制台参数是2个,就运行网络爬虫:

CCrawl iCrawl(argv[2], "visited.all");
   iCrawl.DoCrawl();

其中 argv[2]是inputfile visited.all是outputfile.

在DoCrawl函数里,初始化是把已经访问过的url加入到一个集合中去,

即调用函数GetVisitedUrlMD5(),这个函数里,主要是读取一个文件:

while( getline(ifsMD5,strMD5) ){
   setVisitedUrlMD5.insert(strMD5);
}

 

setVisitedUrlMD5就是一个已经访问过的url集合

同理于 GetVisitedPageMD5();GetIpBlock();

GetUnreachHostMD5();

分别读取文件内容到setVisitedPageMD5,mapIpBlock,setUnreachHostMD5

set<string> setVisitedUrlMD5;
set<string> setVisitedPageMD5;

map<unsigned long,unsigned long> mapIpBlock;

其中 setUnreachHostMD5 是从文件读出不能到达的url,然后对这个url取了一个MD5值,存进内存中这个集合的.

 

这些前期工作做完以后,就开始读取种子文件,也就是开始爬取采用的起始url.

先是打开所有的输出流文件,函数是OpenFilesForOutput().也就是将来爬取得结果存放的文件.这里面包括索引文件(专门的类来打开),visited.url,link4SE.url,link4History.url(这个可能存放的是一篇HTML中的图像链接),unreach host file,visited url md5 file,visited page md5 file.

for(unsigned int i=0; i< NUM_WORKERS; i++){
   if( pthread_create( &tids[i], NULL, start, this))
    cerr << "create threads error" << endl;
}

启动10个线程,每个线程执行的函数是start,参数是this指针

在启动线程的同时,读取种子文件的url

while( getline(ifsSeed, strUrl) ){

//对读到的url进行一些处理后,调用AddUrl(strUrl)函数

AddUrl(strUrl.c_str());

}

也同时读取未访问的url

while( getline(ifsUnvisitedUrl, strUrl) ){

AddUrl(strUrl.c_str());

}

 

 

开看AddUrl函数做了哪些工作

AddUrl(const char * url)

在这个函数里,先判断是否是图像类型链接,是的话就加入m_ofsLink4HistoryFile 集合

string strUrl = url;

if (iUrl.IsImageUrl(strUrl))
{
   if( m_ofsLink4HistoryFile ){
    pthread_mutex_lock(&mutexLink4HistoryFile);
    m_ofsLink4HistoryFile << strUrl << endl;;
    pthread_mutex_unlock(&mutexLink4HistoryFile);
   }
   return;
}

 

在通过函数iUrl.ParseUrlEx(strUrl) ,解析strUrl代表的各种信息,如Host,scheme,port 以及request

如果不是图片链接,就把这个Host的MD5摘要加入到集合setUnvisitedUrlMD5中去,Host来源是iUrl.m_sHost成员.

 

 

CMD5 iMD5;
iMD5.GenerateMD5( (unsigned char*)iUrl.m_sHost.c_str(), iUrl.m_sHost.size() );
string strDigest = iMD5.ToString();

setUnvisitedUrlMD5.insert(strDigest);注意这个保存的是MD5

之后把<host,url>存到一个map映射里去 mmapUrls.insert(mvalType( iUrl.m_sHost, strUrl));

这个mmap里保存的是没有访问过的url,不是MD5,上面的那个集合是用来判断用的,

实际的线程函数会用到mmap

再来看前面说的线程函数start

start(arg)-->fetch(arg)

参数arg是CCrawl对象指针

在函数fetch中,先打开天网索引文件,以便存放结果

string ofsName = DATA_TIANWANG_FILE + "." + CStrFun::itos(pthread_self());
CTianwangFile tianwangFile(ofsName);

再打开一个Link4SEfile文件(Link4SE.raw),ofsName = DATA_LINK4SE_FILE + "." + CStrFun::itos(pthread_self());
CLink4SEFile link4SEFile(ofsName);

在fetch函数里,遍历mmap,取出<host,url>对

multimap<string,string>::iterator it=mmapUrls.begin();

取出url:

string strUrl = (*it).second;

再调用下载函数

(( CCrawl* )arg)->DownloadFile(&tianwangFile,&link4SEFile,iUrl,nGSock);

开始下载实际网页.

在DownloadFile函数里,实际下载的功能由file_length = http.Fetch( strUrlLocation, &downloaded_file, &fileHead, &location, &nSock);这句来实现.

char *downloaded_file = NULL,
   *fileHead = NULL,
   *location = NULL;

下载来的网页文件保存在downloaded_file,fileHead,location内存中.

之后把这些内容作为参数传递进CPage对象里.

CPage iPage(iUrl.m_sUrl, strUrlLocation, fileHead, downloaded_file, file_length);

 

 

对已经爬取了的网页url处理,把它的MD5插入到已经爬取网页url集合中去

iMD5.GenerateMD5( (unsigned char*)iUrl.m_sUrl.c_str(), iUrl.m_sUrl.length() );
strDigest = iMD5.ToString();


if( setVisitedUrlMD5.find(strDigest) != setVisitedUrlMD5.end() ) {

//找到集合中有这个元素,其实

//可以不用检查的
   cout << "!vurl: ";    //1.crawled already
  
   return; //立刻返回
}
  
setVisitedUrlMD5.insert(strDigest);
SaveVisitedUrlMD5(strDigest);//写入已经爬取的url的文件

 

之后 把网页内容写入天网格式文件

SaveTianwangRawData(pTianwangFile, &iUrl, &iPage);

对爬取的网页内容提取超链接,这是用Lex完成的,上篇已经写过了TSE中的Lex流程.

 

先是struct uri page_uri;

uri_parse_string(iPage.m_sUrl.c_str(), &page_uri);

把该网页的url由String转换成结构来存放.

之后调用

hlink_detect_string(iPage.m_sContent.c_str(), &page_uri, onfind, &p);

就是上篇写的处理网页类.

 

再来看看onfind函数

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值