- 浏览: 35641 次
- 性别:
- 来自: 北京
最新评论
-
firefox_hit:
您好,请问在哪里可以下载到此WebSpider的源码呢?我想学 ...
开放源码的网络蜘蛛 -
dying:
谢谢分享,不过写代码没注释的习惯真差
C语言写的多线程下载器 -
zkf53064:
...
C语言写的多线程下载器 -
iranger:
在load中使用LockMode.write是肯定不对的,AP ...
LockMode.UPGRADE 引发的对于Hibernate事务的思考 -
pn2008:
学习。。。。
LockMode.UPGRADE 引发的对于Hibernate事务的思考
http://microsoft.csdn.net/vs/dev%5Fcontest/Ms_rich_Detail.aspx?pointid=102
开发环境:Visual Studio 2005 语言:C++/CLI
作品所要解决的主要问题: 对于给定的网站列表,下载其所有网页到数据库,可以限制抓取深度和吞吐量。
存储的信息包括标题、内容、网页大小、抓取时间、链接数、连接数等等 。
作品的主要应用场景: 可用于数据采集、数据挖掘以及搜索引擎的前期工作。
基于IOCP模型构建,稳定性有保证。
而且有详细的开发文档。
使用说明:
1.直接点击bin目录下的WebSpiderEh.exe,即可开始抓取网站。
2.bin\db.mdb中的sites表配置您要抓取的网站,pages表保存抓取的结果。
3.maxDepth.txt中的数字控制抓取的深度。
4.throughput.txt中的数字控制蜘蛛的吞吐量,一般不用修改,如果您的网速很快,可以将数字调大一点。
谢谢使用,欢迎提出宝贵意见!
如果您下载后觉得好用,或者觉得源码对您有借鉴的价值,请投出您宝贵的一票。
呵呵,这话说的,真是年轻人。
重点是“四不像”,不利于工程化。
C#是全新的,我们不是也转了么。
开发环境:Visual Studio 2005 语言:C++/CLI
作品所要解决的主要问题: 对于给定的网站列表,下载其所有网页到数据库,可以限制抓取深度和吞吐量。
存储的信息包括标题、内容、网页大小、抓取时间、链接数、连接数等等 。
作品的主要应用场景: 可用于数据采集、数据挖掘以及搜索引擎的前期工作。
基于IOCP模型构建,稳定性有保证。
而且有详细的开发文档。
使用说明:
1.直接点击bin目录下的WebSpiderEh.exe,即可开始抓取网站。
2.bin\db.mdb中的sites表配置您要抓取的网站,pages表保存抓取的结果。
3.maxDepth.txt中的数字控制抓取的深度。
4.throughput.txt中的数字控制蜘蛛的吞吐量,一般不用修改,如果您的网速很快,可以将数字调大一点。
谢谢使用,欢迎提出宝贵意见!
如果您下载后觉得好用,或者觉得源码对您有借鉴的价值,请投出您宝贵的一票。
评论
6 楼
firefox_hit
2013-05-30
您好,请问在哪里可以下载到此WebSpider的源码呢?我想学习一下!真是十分感谢!
我还想问您,您十分对动态页面中的需要脚本解析生成的URL的提取有所研究呢?
我还想问您,您十分对动态页面中的需要脚本解析生成的URL的提取有所研究呢?
5 楼
rtdb
2007-11-22
fxsjy 写道
rtdb 写道
我们用VC6过十年了,
但宁愿用C#, 也不想用四不像的C++/CLI
你们不愿意用也没人强迫你,我们年轻人愿意就行了,毕竟新的东西还是值得去尝试的。但宁愿用C#, 也不想用四不像的C++/CLI
重点是“四不像”,不利于工程化。
C#是全新的,我们不是也转了么。
4 楼
fxsjy
2007-11-15
rtdb 写道
我们用VC6过十年了,
但宁愿用C#, 也不想用四不像的C++/CLI
你们不愿意用也没人强迫你,我们年轻人愿意就行了,毕竟新的东西还是值得去尝试的。但宁愿用C#, 也不想用四不像的C++/CLI
3 楼
rtdb
2007-11-15
我们用VC6过十年了,
但宁愿用C#, 也不想用四不像的C++/CLI
但宁愿用C#, 也不想用四不像的C++/CLI
2 楼
fxsjy
2007-11-11
没人感兴趣吗?
看来C++/CLI用的人还是不多,我觉得挺不错的,又可以调Win32 API,又可以用.Net的库。
看来C++/CLI用的人还是不多,我觉得挺不错的,又可以调Win32 API,又可以用.Net的库。
1 楼
fxsjy
2007-11-07
// WebSpiderEh.cpp: 主项目文件。 #include "stdafx.h" #include "InitSock.h" #include "DataUnit.h" #include "HTMLDoc.h" #include "UrlQueue.h" #include "stdio.h" #include "algorithm" #include "map" #include "string" #include "iostream" #define BUFSMALL 1024 //小缓冲区的大小(一次接收) #define BUFBIG 600000 //大缓冲区的大小(整个网页) #define PRONUMBER 2 //并发进程数 #define TIME_OUT_TIME 1 //connect超时时间1秒 #define TIMEOUT_IDLE 500 //防死机*秒 #define TIMEOUT_IOCP INFINITE //IOCP查询周期 #define UPDATE_CYCLE 3 //热门关键词更新的周期(天数) //#define DBG using namespace System; using namespace System::Net; using namespace System::Text; using namespace System::IO; using namespace System::Text::RegularExpressions; using namespace System::Runtime::InteropServices; using namespace System::Collections::Generic; using namespace System::Data; using namespace System::Data::OleDb; using namespace System::Threading; using namespace System::Diagnostics; using namespace std; char * strtochar(String ^s){//将托管String^转化为Native Char* return ( char *)Marshal::StringToHGlobalAnsi(s).ToPointer(); } string Str2str(String^ s){//将托管String^转化为标准string char *ptr=( char *)Marshal::StringToHGlobalAnsi(s).ToPointer(); ptr[s->Length]='\0'; return string(ptr); } String^ strtomd5(String^ text){ return System::Web::Security::FormsAuthentication::HashPasswordForStoringInConfigFile(text,"md5"); } ref class Global{ public: //g_visited是全局变量,记录访问过的网页,避免重复访问 static Dictionary<String^,int> g_visited; //g_titleused是全局变量,记录出现过的标题,以达到标题去重的效果 static Dictionary<String^,int> g_titleused; //static IndexWriter^ g_writer; //g_priorities 保存每个网站的优先级 static Dictionary<String^,int> g_priorities; static OleDbConnection^ g_conn; static int postAmount=0; static const int throughput=int::Parse(File::OpenText("throughput.txt")->ReadLine()); static const int max_depth=int::Parse(File::OpenText("maxDepth.txt")->ReadLine()); }; // 初始化Winsock库 CInitSock theSock; HANDLE hCompletion;//完成端口 //控制IO查询线程是否继续工作 bool g_iogo; typedef struct _PER_HANDLE_DATA // per-handle数据 { SOCKET s; // 对应的套节字句柄 sockaddr_in addr; // 服务器地址 } PER_HANDLE_DATA, *PPER_HANDLE_DATA; typedef struct _PER_IO_DATA // per-I/O数据 { OVERLAPPED ol; // 重叠结构 char buf[BUFBIG]; // 数据缓冲区 int nOperationType; // 操作类型 char url[BUFSMALL]; //网址 int top; //缓冲区指针 #define OP_READ 1 #define OP_WRITE 2 } PER_IO_DATA, *PPER_IO_DATA; String^ getDomain(String^ url){ Uri^ uri=gcnew Uri(url); String^ host=uri->Host; int i=host->IndexOf("."); return host->Substring(i+1); } void PostGet(String^ url){ try{ String^ urlflag=url->ToLower(); if(Global::g_visited.ContainsKey(urlflag))return ; if(url->Length>255)return ; if(url->EndsWith(".zip") || url->EndsWith(".gz") || url->EndsWith(".rar") || url->EndsWith(".exe") || url->EndsWith(".exe") || url->EndsWith(".jpg") || url->EndsWith(".png") || url->EndsWith(".tar") || url->EndsWith(".chm") || url->EndsWith(".iso")|| url->EndsWith(".gif") || url->EndsWith(".csv") || url->EndsWith(".pdf") || url->EndsWith(".doc")) return; SOCKET cs; Uri uri(url); String^ host=uri.Host; //域名 String^ destWeb=uri.PathAndQuery; //绝对URL路径 String^ IP=""; IP=Dns::GetHostEntry(host)->AddressList[0]->ToString(); //IP地址 int port=uri.Port; //端口 SOCKADDR_IN servAddr; servAddr.sin_family=AF_INET; servAddr.sin_addr.S_un.S_addr=inet_addr(strtochar(IP)); servAddr.sin_port=htons(port); cs=::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if(INVALID_SOCKET==cs){ Console::WriteLine(L"创建套接字失败"); return ; } if(::connect(cs,(SOCKADDR*)&servAddr,sizeof(SOCKADDR))==SOCKET_ERROR){ Console::WriteLine(WSAGetLastError()); return ; } /*int error=-1, len; len = sizeof(int); timeval tm; fd_set set; unsigned long ul = 1; ioctlsocket(cs, FIONBIO, &ul); //设置为非阻塞模式 bool ret = false; if( connect(cs, (struct sockaddr *)&servAddr, sizeof(servAddr)) == -1) { tm.tv_sec = TIME_OUT_TIME; tm.tv_usec = 0; FD_ZERO(&set); FD_SET(cs, &set); if( select(cs+1, NULL, &set, NULL, &tm) > 0) { getsockopt(cs, SOL_SOCKET, SO_ERROR, (char *)&error, &len); if(error == 0) ret = true; else ret = false; } else ret = false; } else ret = true; ul = 0; ioctlsocket(cs, FIONBIO, &ul); //设置为阻塞模式 if(!ret){ closesocket(cs); return ; }*/ char getstr[BUFSMALL]={0}; sprintf_s(getstr,"GET %s HTTP/1.0\r\nHost: %s\r\nAccept: */*\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)\r\nReferer: %s\r\nPragma: no-cathe\r\nCathe-Control: no-cathe\r\nConnection: close\r\n\r\n",strtochar(destWeb),strtochar(host),strtochar(url)); //取得HTTP报头 int sendlen=strlen(getstr); ::send(cs,getstr,sendlen,0); //Console::WriteLine(url); // 建立新连接之后,为它创建一个per-handle数据,并将它们关联到完成端口对象。 PPER_HANDLE_DATA pPerHandle = (PPER_HANDLE_DATA)::GlobalAlloc(GPTR, sizeof(PER_HANDLE_DATA)); pPerHandle->s = cs; memcpy(&pPerHandle->addr, &servAddr, sizeof(servAddr)); ::CreateIoCompletionPort((HANDLE)pPerHandle->s, hCompletion, (DWORD)pPerHandle, 0); // 投递一个接收请求 PPER_IO_DATA pPerIO = (PPER_IO_DATA)::GlobalAlloc(GPTR, sizeof(PER_IO_DATA)); pPerIO->buf[0]='\0'; pPerIO->nOperationType=OP_READ; pPerIO->top=0; memcpy(pPerIO->url,strtochar(url),url->Length); WSABUF buf; buf.buf=pPerIO->buf; buf.len=BUFSMALL; DWORD nFlags=0; DWORD dwTrans=0; ::WSARecv(pPerHandle->s, &buf, 1, &dwTrans, &nFlags, &pPerIO->ol, NULL); Global::g_visited[urlflag]=1; //标志为访问过了 Global::postAmount++; //Console::WriteLine(Global::postAmount); //Console::WriteLine(UrlQueue::g_urlqueue->size()); //return 1; }catch(Exception^ ex){ #ifdef DBG Console::WriteLine(ex->Message); #endif delete ex; //System::GC::Collect(); //System::GC::WaitForPendingFinalizers(); //return 0; } } //addpage把分页好的网页数据暂存到access数据库中去 int addPage(String^ URL,String^ Title,String^ PlainText,String^ LinkText,int Size,String^ Host,int OutDegree,int Priority){ OleDbConnection^ conn=Global::g_conn; if(conn==nullptr || conn->State!=System::Data::ConnectionState::Open){ String^ connstr="Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+System::AppDomain::CurrentDomain->BaseDirectory+"\\db.mdb"; //Console::WriteLine(connstr); conn=gcnew OleDbConnection(connstr); conn->Open(); Global::g_conn=conn; } try{ Regex^ reg=gcnew Regex("\\W{1}(?<tt>[0-9a-zA-Z_:,、;《》“”\u4e00-\u9fa5]{10,30})\\W"); String^ tmp=""; if(!Global::g_titleused.ContainsKey(Title)){ Global::g_titleused[Title]=1; } else{ Match^ mc=reg->Match(PlainText); if(mc->Success){ tmp=mc->Groups["tt"]->ToString(); while(Global::g_titleused.ContainsKey(tmp)){ mc=mc->NextMatch(); if(!mc->Success){ tmp=Title; break; } tmp=mc->Groups["tt"]->ToString(); } if(Title->Equals(tmp))Priority--; Title=tmp; Global::g_titleused[Title]=1; } } if(("http://"+Host)->ToLower()==URL->ToLower())Priority+=15; if(("http://"+Host+"/")->ToLower()==URL->ToLower())Priority+=15; if(("http://"+Host)->ToLower()==URL->ToLower() && URL->Split('.')->Length<=4)Priority+=15; if(("http://"+Host+"/")->ToLower()==URL->ToLower() && URL->Split('.')->Length<=4)Priority+=15; if(("http://www."+getDomain(URL))->ToLower()==URL->ToLower())Priority++; if(("http://www."+getDomain(URL)+"/")->ToLower()==URL->ToLower())Priority++; //String^ connstr="provider=microsoft.jet.oledb.4.0;data source=" + AppDomain::CurrentDomain::get()->BaseDirectory + "\\db.mdb"; OleDbDataAdapter^ da=gcnew OleDbDataAdapter("select 1 from pages where [url]='"+URL+"'",conn); DataSet^ ds=gcnew DataSet(); da->Fill(ds); if(ds->Tables[0]->Rows->Count>0){ //delete conn; return 1; } StringBuilder^ sb=gcnew StringBuilder(); sb->Append("insert into Pages([URL],[Title],[PlainText],[LinkText],[Size],[Host],[UpdateTime],[OutDegree],[Priority]) values('"); sb->Append(URL)->Append("','"); sb->Append(Title)->Append("','"); sb->Append(PlainText)->Append("','"); sb->Append(LinkText)->Append("',"); sb->Append(Size)->Append(",'"); sb->Append(Host)->Append("','"); sb->Append(DateTime::Now.ToString())->Append("',"); sb->Append(OutDegree.ToString())->Append(","); sb->Append(Priority.ToString())->Append(")"); OleDbCommand^ cmd=gcnew OleDbCommand(); cmd->Connection=conn; cmd->CommandText=sb->ToString(); cmd->ExecuteNonQuery(); //conn->Close(); //delete conn; delete sb; delete PlainText; delete URL; delete Title; delete LinkText; delete Host; /*HANDLE m_hMutex = OpenMutex( MUTEX_ALL_ACCESS, // request full access FALSE, // handle not inheritable L"mymutex"); // object name if(m_hMutex==NULL){ m_hMutex = CreateMutex(NULL, TRUE, L"mymutex"); } else{ WaitForSingleObject(m_hMutex,INFINITE); } String^ indexpath=AppDomain::CurrentDomain::get()->BaseDirectory + "\\index"; IndexWriter^ writer; try{ writer=gcnew IndexWriter(indexpath,gcnew Standard::StandardAnalyzer(),false); } catch(Exception^ ex){ delete ex; writer=gcnew IndexWriter(indexpath,gcnew Standard::StandardAnalyzer(),true); } IndexReader^ reader=IndexReader::Open(indexpath); reader->Delete(gcnew Term("url",URL)); reader->Close(); Document^ doc=gcnew Document(); doc->Add(gcnew Field("title",Title,Field::Store::YES,Field::Index::TOKENIZED,Field::TermVector::WITH_POSITIONS_OFFSETS)); doc->Add(gcnew Field("context", PlainText, Field::Store::YES, Field::Index::TOKENIZED, Field::TermVector::WITH_POSITIONS_OFFSETS)); doc->Add(Field::UnIndexed("host", Host)); doc->Add(Field::UnIndexed("page_size", Size.ToString())); doc->Add(gcnew Field("update_time", DateTime::Now.ToString(),Field::Store::YES,Field::Index::UN_TOKENIZED)); doc->Add(gcnew Field("priority", Priority.ToString(),Field::Store::YES,Field::Index::UN_TOKENIZED)); doc->Add(Field::Keyword("url", URL)); writer->AddDocument(doc); writer->Close(); ::ReleaseMutex(m_hMutex);*/ return 0; }catch(Exception^ ex){ #ifdef DBG Console::WriteLine(ex->Message); #endif delete ex; //delete conn; delete PlainText; delete URL; delete Title; delete LinkText; delete Host; //System::GC::Collect(); //System::GC::WaitForPendingFinalizers(); return 1; } //System::GC::Collect(); //System::GC::WaitForPendingFinalizers(); } int WebCut(LPVOID lpParam){ //分解并保存网页的函数 PPER_IO_DATA pPerIO=(PPER_IO_DATA)lpParam; char* start=NULL; //正文开始的指针 char* ix=NULL,*ix2=NULL; //"charset="这个字符串的位置 char cdbuf[20]={0};//编码方式 int cdbuftop=0; char key1[]="\r\n\r\n"; char key2[]="charset="; char key3[]="encoding="; try{ start=std::search(pPerIO->buf,pPerIO->buf+pPerIO->top,key1,key1+strlen(key1)); if(start==pPerIO->buf+pPerIO->top)start=pPerIO->buf; ix=std::search(pPerIO->buf,pPerIO->buf+pPerIO->top,key2,key2+strlen(key2)); ix2=std::search(pPerIO->buf,pPerIO->buf+pPerIO->top,key3,key3+strlen(key3)); if(ix!=(pPerIO->buf+pPerIO->top)){ ix+=strlen("charset="); while(*ix!='"' && *ix!='\n' && *ix!='\r' && cdbuftop<20){ cdbuf[cdbuftop++]=*ix; ix++; } cdbuf[cdbuftop]='\0'; } else if(ix2!=pPerIO->buf+pPerIO->top){ ix2+=strlen("encoding="); String^ str=gcnew String(ix2,0,12,Encoding::Default); Regex reg("(?<CDING>(UTF-8)|(GB2312))",RegexOptions::IgnoreCase); Match^ mc=reg.Match(str); String^ tempcd=mc->Groups["CDING"]->ToString(); memcpy(cdbuf,strtochar(tempcd),tempcd->Length); } else{ strcpy_s(cdbuf,"GB2312"); } String^ cding=% String(cdbuf); if(cding->ToUpper()=="UTF8")cding="UTF-8"; String^ html; int htmllen=strlen(start); while(htmllen<BUFBIG-1 && (start[htmllen+1]!='\0' || start[htmllen+2]!='\0')){ //Console::WriteLine(htmllen); htmllen+=strlen(start+htmllen+1)+1; if(htmllen>=BUFBIG){ htmllen=BUFBIG; break; } } //Console::WriteLine(htmllen); try{ html=gcnew String(start,0,htmllen,Encoding::GetEncoding(cding));//网页正文 }catch(Exception^ ex){ #ifdef DBG Console::WriteLine(ex->Message); #endif delete ex; //System::GC::Collect(); //System::GC::WaitForPendingFinalizers(); html=gcnew String(start,0,pPerIO->top,Encoding::Default);//网页正文 } HTMLDoc^ doc=gcnew HTMLDoc(html,%String(pPerIO->url));//网页分析模板 ArrayList^ al=doc->GetInnerLinks(); //获得所有站内链接 for(int i=0;i<al->Count;i++){ String^ urlflag=((String^)al[i])->ToLower() ; if(!Global::g_visited.ContainsKey(urlflag)){ if(urlflag->EndsWith("/")){ int ix=urlflag->LastIndexOf("/"); if(Global::g_visited.ContainsKey(urlflag->Substring(0,ix)))continue; } try{ if(Uri(al[i]->ToString()).Segments->Length<=Global::max_depth){ UrlQueue::g_urlqueue->push(gcnew UrlAtom((String^)al[i]));//放入网址队列 } } catch(Exception^ ex){ delete ex; } } } String^ URL=gcnew String(pPerIO->url); if(Global::g_priorities.ContainsKey(getDomain(URL))){ addPage(URL,doc->GetTitle(),doc->GetPlainText(),doc->GetLinkText(),doc->GetSize(),Uri(URL).Host,al->Count,Global::g_priorities[getDomain(URL)]); Console::WriteLine(URL); //打印该完成页的网址 } else{ addPage(URL,doc->GetTitle(),doc->GetPlainText(),doc->GetLinkText(),doc->GetSize(),Uri(URL).Host,al->Count,0); Console::WriteLine(URL); //打印该完成页的网址 } } catch(Exception^ ex){ #ifdef DBG Console::WriteLine(ex->Message); #endif delete ex; //System::GC::Collect(); //System::GC::WaitForPendingFinalizers(); } return 0; } //判断主机是否相关 bool hostrelated(String^ a,String^ b){ try{ Match^ mc1=Regex("\\.([^.]+)\\.").Match(a); Match^ mc2=Regex("\\.([^.]+)\\.").Match(b); if(mc1->Success && mc2->Success && mc1->Groups->Count>1 && mc2->Groups->Count>1 && mc1->Groups[1]->Value->ToLower()==mc2->Groups[1]->Value->ToLower()){ return true; } else return false; } catch(Exception^ ex) { #ifdef DBG Console::WriteLine(ex.Message); #endif delete ex; return false; } } //ServerThread线程函数用于查询和操作完成端口 DWORD WINAPI ServerThread(LPVOID lpParam) { // 得到完成端口对象句柄 HANDLE hCompletion = (HANDLE)lpParam; DWORD dwTrans; PPER_HANDLE_DATA pPerHandle; PPER_IO_DATA pPerIO; while(g_iogo) { // 在关联到此完成端口的所有套节字上等待I/O完成 BOOL bOK = ::GetQueuedCompletionStatus(hCompletion, &dwTrans, (LPDWORD)&pPerHandle, (LPOVERLAPPED*)&pPerIO, TIMEOUT_IOCP); try{ if(!bOK) // 在此套节字上有错误发生 { try{ if(pPerHandle!=NULL && pPerHandle->s!=INVALID_SOCKET) ::closesocket(pPerHandle->s); if(pPerHandle!=NULL) ::GlobalFree(pPerHandle); if(pPerIO!=NULL) ::GlobalFree(pPerIO); }catch(Exception^ ex){ #ifdef DBG Console::WriteLine(ex->Message); #endif delete ex; } Global::postAmount--; continue; } if(dwTrans == 0 && // 套节字被对方关闭(既网页下载完毕了) (pPerIO->nOperationType == OP_READ || pPerIO->nOperationType == OP_WRITE)) { Global::postAmount--; if(String(pPerIO->buf,0,1024).IndexOf("200 OK")>-1){ //网页存在 WebCut((LPVOID)pPerIO); //处理网页 //printf(pPerIO->buf); } try{ if(pPerHandle!=NULL && pPerHandle->s!=INVALID_SOCKET) ::closesocket(pPerHandle->s); if(pPerHandle!=NULL) ::GlobalFree(pPerHandle); if(pPerIO!=NULL) ::GlobalFree(pPerIO); }catch(Exception^ ex){ #ifdef DBG Console::WriteLine(ex->Message); #endif delete ex; } continue; } //Content-Type: Regex reg("\\sContent-Type:\\s(?<TYPE>[^\\s]+)\\s"); Regex reg2("\\sLocation:\\s(?<LOCATION>[^\\s]+)\\s"); Match^ mc; Match^ mc2; DWORD nFlags=0; switch(pPerIO->nOperationType) // 通过per-I/O数据中的nOperationType域查看什么I/O请求完成了 { case OP_READ: // 完成一个接收请求 //pPerIO->buf[dwTrans]='\0'; if(pPerIO->top<=BUFSMALL && pPerIO!=NULL){ mc=reg.Match(% String(pPerIO->buf)); mc2=reg2.Match(% String(pPerIO->buf)); //防止下载非文本文件 if(!mc->Success || (mc->Groups[L"TYPE"]->ToString()->Length>=5 && mc->Groups[L"TYPE"]->ToString()->Substring(0,5)->ToLower()!="text/") || mc->Groups[L"TYPE"]->ToString()->Length<5){ try{ if(pPerHandle!=NULL && pPerHandle->s!=INVALID_SOCKET) ::closesocket(pPerHandle->s); if(pPerHandle!=NULL) ::GlobalFree(pPerHandle); if(pPerIO!=NULL) ::GlobalFree(pPerIO); }catch(Exception^ ex){ #ifdef DBG Console::WriteLine(ex->Message); #endif delete ex; } continue; } if(mc2->Success){ //如果有重定向 String^ newurl=Uri(% Uri(% String(pPerIO->url)),mc2->Groups[L"LOCATION"]->ToString()).ToString(); String^ url=gcnew String(pPerIO->url); try{ if(pPerHandle!=NULL && pPerHandle->s!=INVALID_SOCKET) ::closesocket(pPerHandle->s); if(pPerHandle!=NULL) ::GlobalFree(pPerHandle); if(pPerIO!=NULL) ::GlobalFree(pPerIO); }catch(Exception^ ex){ #ifdef DBG Console::WriteLine(ex->Message); #endif delete ex; } Uri^ newuri=gcnew Uri(newurl); if(hostrelated(newuri->Host,Uri(url).Host)) { if(Global::g_priorities.ContainsKey(getDomain(url))) Global::g_priorities[getDomain(newurl)]=Global::g_priorities[getDomain(url)]; PostGet(newurl); continue; } } } WSABUF buf; //printf("%d\n",dwTrans); pPerIO->top+=dwTrans; if(pPerIO->top>(BUFBIG-1)){//防止网页过大而OverFlow try{ if(pPerHandle!=NULL && pPerHandle->s!=INVALID_SOCKET) ::closesocket(pPerHandle->s); if(pPerHandle!=NULL) ::GlobalFree(pPerHandle); if(pPerIO!=NULL) ::GlobalFree(pPerIO); }catch(Exception^ ex){ #ifdef DBG Console::WriteLine(ex->Message); #endif delete ex; } continue; } //pPerIO->buf[pPerIO->top]='\0'; buf.buf=pPerIO->buf+pPerIO->top; buf.len=BUFSMALL ; nFlags=0; ::WSARecv(pPerHandle->s, &buf, 1, &dwTrans, &nFlags, &pPerIO->ol, NULL); break; case OP_WRITE: // 完成一个发送请求,此处暂时无用 //Sleep(10); break; } } catch(System::AccessViolationException^ ex){ #ifdef DBG Console::WriteLine(ex->Message); #endif delete ex; Global::postAmount--; //System::GC::Collect(); //System::GC::WaitForPendingFinalizers(); } } return 0; } int main(array<System::String ^> ^args) { String^ appPath=AppDomain::CurrentDomain::get()->BaseDirectory; String^ connstr="provider=microsoft.jet.oledb.4.0;data source=" +appPath+ "\\db.mdb"; //String^ connstr=String^ connstr="Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+System::AppDomain::CurrentDomain->BaseDirectory+"\\db.mdb"; if(args->Length==0){ /*String^ lifePath="c:\\windows\\system32\\host.dll"; bool fExist=System::IO::File::Exists(lifePath); if(!fExist){ StreamWriter^ sw=File::CreateText(lifePath); sw->WriteLine("1"); sw->Close(); } else{ StreamReader^ sr=gcnew StreamReader(lifePath,System::Text::Encoding::Default); int costTimes=int::Parse(sr->ReadLine()); sr->Close(); if(costTimes==10) return 0; Console::WriteLine("还剩{0}次运行的机会。",10-costTimes); StreamWriter^ sw = gcnew StreamWriter (lifePath,false,System::Text::Encoding::Default); sw->WriteLine((costTimes+1).ToString()); sw->Close(); }*/ OleDbConnection^ conn=gcnew OleDbConnection(connstr); //Console::WriteLine("Author:Sunjoy@ICT"); //Console::WriteLine("E-mail:ccnusjy@gmail.com"); Console::WriteLine("正在导入要搜索的站点..."); conn->Open(); //::CreateMutex(NULL,false,L"mymutext"); //删除原有的页(上次爬虫运行的结果) OleDbCommand^ initcmd=gcnew OleDbCommand("delete from Pages",conn); try{ initcmd->ExecuteNonQuery(); }catch(Exception^ ex){ delete ex; } //更新热门关键词 //initcmd=gcnew OleDbCommand("update KeyWords set rank=0,AddTime=now() where datediff('d',AddTime,now())>"+UPDATE_CYCLE,conn); //initcmd->ExecuteNonQuery(); OleDbCommand^ cmd=gcnew OleDbCommand("select * from sites order by Priority desc",conn); OleDbDataReader^ rd=cmd->ExecuteReader(); array<String^> ^params=gcnew array<String^>(PRONUMBER); int ct=0; while(rd->Read()){ if(params[ct%PRONUMBER]==nullptr) params[ct%PRONUMBER]=rd["URL"]->ToString()->Trim(); else params[ct%PRONUMBER]=params[ct%PRONUMBER]+" "+rd["URL"]->ToString()->Trim(); ct++; } for(int j=0;j<PRONUMBER;j++){ if(params[j]!=nullptr){ Process^ p=gcnew Process(); p->StartInfo->FileName=appPath+"\\WebSpiderEH.exe"; p->StartInfo->Arguments=params[j]; Console::WriteLine("{----"+params[j]+"---}"); p->StartInfo->UseShellExecute=false; p->Start(); } } rd->Close(); delete rd; conn->Close(); delete conn; //Console::ReadLine(); } else{ String^ indexpath=AppDomain::CurrentDomain::get()->BaseDirectory + "\\index"; //Console::WriteLine("正在校验本程序的版权。。。"); //else //Console::WriteLine("=====合法程序====="); int idletimes=0; hCompletion = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0);//新建一个完成端口 g_iogo=true; try{ HANDLE thd=::CreateThread(NULL, 0, ServerThread, (LPVOID)hCompletion, 0, 0);//启动查询完成端口线程 ::CloseHandle(thd); //减少引用计数 }catch(Exception^ ex){ delete ex; #ifdef DBG Console::WriteLine(ex->Message); #endif } for(int i=0;i<args->Length;i++){ OleDbConnection^ conn=gcnew OleDbConnection(connstr); conn->Open(); OleDbCommand^ cmd=gcnew OleDbCommand("select Priority from Sites where URL='"+args[i]+"'",conn); OleDbDataReader^ rd= cmd->ExecuteReader(); if(rd->Read()){ String^ tmpdomain=""; try{ tmpdomain=getDomain(args[i]); } catch(Exception^ ex){ delete ex; Console::WriteLine("不规范或不完整的URL{0},请您检查",args[i]); continue; } Global::g_priorities[tmpdomain]=int::Parse(rd["Priority"]->ToString()); } UrlQueue::g_urlqueue->push(gcnew UrlAtom(args[i])); } while(true) { String^ url=UrlQueue::g_urlqueue->pop()->url; while(url=="" || url==nullptr){ if(idletimes==TIMEOUT_IDLE) goto theEnd; else{ Sleep(1000); idletimes++; } url=UrlQueue::g_urlqueue->pop()->url; } //Console::WriteLine(Global::throughput); Regex^ re = gcnew Regex("(?<h>[^\\x00-\\xff]+)"); Match^ mc = re->Match(url); if (mc->Success) { String^ han = mc->Groups["h"]->Value; url = url->Replace(han, System::Web::HttpUtility::UrlEncode(han, Encoding::GetEncoding("GB2312"))); } try{ gcnew Uri(url); } catch(Exception^ ex){ delete ex; //Console::WriteLine("不规范的URL:{0},请您检查",url); continue; }; DateTime t1=DateTime::Now; PostGet(url); DateTime t2=DateTime::Now; TimeSpan delta=t2-t1; int maxT=10; //Console::WriteLine(delta.TotalMilliseconds); if(delta.TotalMilliseconds<maxT){ Sleep(maxT-(int)delta.TotalMilliseconds); } DateTime b1=DateTime::Now; while(Global::postAmount>Global::throughput){ Sleep(1000); TimeSpan dlt=DateTime::Now-b1; if(dlt.TotalMinutes>1) Global::postAmount/=2; } idletimes=0; }//endwhile g_iogo=false; theEnd: Console::WriteLine("====OVER===="); //::WinExec("tskill WebSpiderEh",SW_HIDE); } return 0; }
相关推荐
综上所述,这个“蜘蛛爬虫源码分享”提供的不仅是一段代码,而是一个全面了解和实践网络爬虫技术的机会。通过研究和运行这个源码,我们可以加深对爬虫工作原理的理解,提升自己的编程技能,并为未来的项目打下坚实...
【PHP实例开发源码-蜘蛛侠淘宝客网站源码 php版.zip】是一个包含PHP源代码的压缩包,专用于构建一个淘宝客类型的网站。淘宝客是一种网络推广模式,通过分享商品链接并引导用户购买,推广者可以获得佣金。该源码可能...
标题中的“抢先式多线程网络蜘蛛”是一个网络爬虫程序,它采用了多线程技术来提高抓取网页数据的效率。在IT行业中,网络爬虫是用于自动抓取互联网信息的一种程序,常用于数据分析、搜索引擎索引更新等场景。这里的...
1. **搜索引擎蜘蛛(也称为网络爬虫或BOT)**:搜索引擎为了更新索引,会派出自动程序(即蜘蛛)遍历互联网上的网页。这些蜘蛛遵循网站的robots.txt文件规则,抓取网页内容,以便将新的和更新的信息纳入搜索引擎的...
5、完全开放源码,第三方组件需要自己下载。 6、在内网服务器上运行2年,经过若干次代码重构和优化。 7、提供规则表达式验证工具。 由于是独立开发,代码没有文档资料,有兴趣的可以钻研代码,提高delphi网络开发的...
"蜘蛛网络城市 v1.0" 是一个基于动网论坛7.0SP2程序内核构建的在线社区平台。这个项目可能是一个开源或共享的源代码版本,允许用户下载、研究和修改源码,以便自定义或开发自己的论坛系统。 动网论坛(DvBBS)是...
在描述中提到,“使用java开发的游戏项目源码,可用于毕业设计、课程设计、练手学习等”,这表明这个项目不仅是一个完整的可运行游戏,还是一份开放源代码的教学资源。学生或初学者可以利用这些源代码作为参考,进行...
多线程网络蜘蛛 网页定向采集 多语言网页编码自动识别 哈希表网页去重 智能网页正文抽取 基于词库的智能中文分词 中文分词词库管理 海量数据毫秒级全文检索 缓存技术 网页快照 高级搜索 竞价排名
该压缩包文件名为"taobao_crawled-master_商城_taobao_淘宝爬虫_淘宝商城商品信息爬虫_源码.zip",从标题和描述中我们...实际源码内容会根据开发者的设计和实现方式有所不同,但这些是网络爬虫开发中常见的技术环节。
新增地图搜索和视频搜索!修复风云榜,竞价排名bug!搜查找3.1.1功能:搜查找搜索引擎软件蜘蛛组件包括三大功能模块:链接采集、网页分析、无效网页扫描;...客户端蜘蛛系统和web蜘蛛系统16仿百度开放平台
本程序完全高仿百度,谷歌,有自主开发的蜘蛛智能抓取网页功能,非网络上仅仅只是界面模仿的免费程序!程序包含24大功能!1.网页搜索2.搜索风云榜3.网址导航4.竞价排名5.蜘蛛智能抓取网页6.网站qp值智能排名7.后台...
网络蜘蛛采用多线程并发采集网页,结合高效的采集机制和策略部署,最大限度提高网页采集的效率。支持网页定向采集,垂直搜索引擎提高数据质量和相关度的关键技术,用户可以自定义采集规则针对特定网页进行采集。支持...
爬虫,也称为网络蜘蛛或自动索引器,是一种用于自动化地从互联网上抓取信息的程序。itsucks爬虫基于Java开发,这意味着它具有跨平台的特性,无论你是在Windows、Mac还是Linux系统上,都能顺利运行。Java作为一种强大...
这款软件利用了各种网站的查询和搜索功能,以吸引网络爬虫(即“蜘蛛爬虫”)对目标网站进行抓取,增强网站的在线可见性。 【描述】中提到,该工具设计的主要目标是为网站所有者提供一种方法,通过自动化过程在多个...
多线程网络蜘蛛 网页定向采集 多语言网页编码自动识别 哈希表网页去重 智能网页正文抽取 基于词库的智能中文分词 中文分词词库管理 海量数据毫秒级全文检索 缓存技术 网页快照 高级...
目前程序免费使用,开放全部功能。 新增功能: 1.可生成并网页缩略图 2.增加网页数据更新功能 3.修正了前一版本占用资源大\功能不完善的bug. 主要功能: 1. 1分布式数据库采集与存储。 蜘蛛程序和数据库...
3. **端口扫描**:端口扫描是网络安全领域的一个概念,通常用于检测服务器上开放的服务。在Java中,可以使用Socket类来尝试连接到特定端口,从而确定其是否开放。 4. **GUI(图形用户界面)编程**:聊天工具、中国...
现在网上的搜索小偷源码除了火端搜索程序几乎都无法使用,因为只有火端网络在不断完善不断更新这套搜索程序。 火端搜索程序给很多站长带来了很大的好处,很多站长用来做网站SEO、引蜘蛛甚至经过二次开发后做站群,...
`saltyfish-spider`,中文名“咸鱼蜘蛛”,是一款开源的免费网络爬虫软件。这个项目名为`saltyfish-master_Free!_saltyfishspider_`,暗示了它是`saltyfish-spider`的主要分支或最新版本,而且是完全免费的。在IT...
有而基于Unix/Linux平台的软件防火墙大家一般接触较少,受益于开放源码运行,目前基于Unix/Linux平台的软件防火墙如雨后春笋般不断推出,这些软件防火墙大多是免费的,常见的有海蜘蛛、RouterOS、m0n0Wall、...