乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      web信息的搜集---Url.h+Url.cpp

       閑來(lái)看看 2013-01-18

      web信息的搜集---Url.h+Url.cpp

      /*

       * Url.h

       * Created on: 2011-10-6

       *      Author: qiuxiong

       * CUrl類的作用:

       * 解析URL,構(gòu)造HTTP請(qǐng)求報(bào)文,發(fā)送給目標(biāo)服務(wù)器.

       * URL的通用形式是:

       * scheme://hostname[:port][/path][;params][?query][#fragment]

       * scheme 表示協(xié)議名稱,例如http,ftp,mailto等等

       * hostname 表示主機(jī)號(hào),其實(shí)就是該主機(jī)對(duì)應(yīng)的因特網(wǎng)域名

       * port 表示端口號(hào)

       * path 表示URL路徑

       * params 表示對(duì)象參數(shù)

       * query 表示查詢信息,也經(jīng)常記為request

       * fragment 表示片段標(biāo)識(shí)

       */

      #ifndef URL_H_

      #define URL_H_

      #include<string>

      using namespace std;

      const unsigned int URL_LEN=256;//URL最大長(zhǎng)度

      const unsigned int HOST_LEN=256;//主機(jī)號(hào)的最大長(zhǎng)度

      const int DEFAULT_HTTP_PORT=80;//HTTP默認(rèn)的端口號(hào)為80

      const int DEFAULT_FTP_PORT=21;//FTP默認(rèn)的端口號(hào)為21

      //自定義的枚舉類型:表示協(xié)議類型,有HTTP協(xié)議,F(xiàn)TP協(xié)議,其他的無(wú)效協(xié)議

      enum url_scheme{SCHEME_HTTP,SCHEME_FTP,SCHEME_INVALID};

      class CUrl

      {

      public:

      string m_sUrl;//URL字符串

      enum url_scheme m_eScheme;//URL解析出的協(xié)議類型

      string m_sHost;//URL解析出的主機(jī)號(hào)

      int m_nPort;//URL解析出的端口號(hào)

      string m_sPath;//URL解析出的請(qǐng)求資源

      public:

      CUrl();

      ~CUrl();

      bool ParseUrlEx(string strUrl);//解析是不是HTTP協(xié)議的URL,不是返回FALSE,否則進(jìn)一步解析URL對(duì)應(yīng)的協(xié)議名稱,主機(jī)號(hào),端口號(hào),請(qǐng)求資源賦值給成員變量,最后返回TRUE

      //真正的解析URL的函數(shù)

      void ParseUrlEx(const char *url,char *protocol,int lprotocol,char *host,int lhost,char *request,int lrequest,int *port);

      char *GetIpByHost(const char *host);//通過(guò)主機(jī)號(hào)得到IP字符串

      bool IsValidHost(const char *host);//判斷該主機(jī)號(hào)是不是有效的主機(jī)號(hào)

      bool IsForeignHost(string host);//判斷該主機(jī)號(hào)是否為外國(guó)主機(jī)號(hào)

      bool IsImageUrl(string url);//判斷該URL是否為圖片鏈接

      bool IsValidIp(const char *ip);//判斷該IP字符串是否有效

      bool IsVisitedUrl(const char *url);//判斷該URL是否訪問(wèn)過(guò)

      bool IsUnReachedUrl(const char *url);//----沒(méi)有實(shí)現(xiàn)---------

      bool IsValidHostChar(char ch);//判斷該字符是否為構(gòu)成主機(jī)號(hào)的字符

      private:

      void ParseScheme(const char *url);//解析出URL所以對(duì)應(yīng)的協(xié)類型

      };

      #endif /* URL_H_ */

      /*

       *Url.cpp

       * Created on: 2011-10-6

       *      Author: qiuxiong

       * 有了URL搜集系統(tǒng)就可以根據(jù)URL的標(biāo)識(shí)抓取其對(duì)應(yīng)的網(wǎng)頁(yè)

       */

      #include<iostream>

      #include<string>

      #include<sys/socket.h>

      #include<netdb.h>

      #include "Http.h"

      #include "Tse.h"

      #include "Url.h"

      #include "Md5.h"

      #include "StrFun.h"

      //DNS緩存:我們不能每次解析出了一個(gè)主機(jī)號(hào)就交給DNS server來(lái)得到IP,建立一個(gè)DNS緩存,防止出現(xiàn)類似于拒絕訪問(wèn)攻擊的作用

      map<string,string>mapCacheHostLookup;

      //這個(gè)set容器保存的是已經(jīng)訪問(wèn)過(guò)的URL對(duì)應(yīng)的MD5值

      extern set<string>setVisitedUrlMD5;//

      extern map<unsigned long ,unsigned long>mapIpBlock;//

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

      pthread_mutex_t mutexCacheHost=PTHREAD_MUTEX_INITIALIZER;//線程的互斥變量初始化

      //自定義協(xié)議類-端口-可以訪問(wèn),例如 "http://" 80 1

      struct scheme_data

      {

      char *leading_string;

      int default_port;

      int enabled;

      };

      static struct scheme_data supported_schemes[]=

      {

      {"http://",DEFAULT_HTTP_PORT,1},

      {"ftp://",DEFAULT_FTP_PORT,1},

      {NULL,-1,0}

      };

      //解析出URL所以對(duì)應(yīng)的協(xié)議類型,然后將協(xié)議類型賦值給成員變量m_eScheme

      void CUrl::ParseScheme(const char *url)

      {

      int i;

      for(i=0;supported_schemes[i].leading_string;i++)

      if(strncasecmp(url,supported_schemes[i].leading_string,strlen(supported_schemes[i].leading_string))==0)

      {

      if(supported_schemes[i].enabled)

      {

      this->m_eScheme=(enum url_scheme)i;//強(qiáng)制轉(zhuǎn)化為枚舉類型

      return;

      }

      else

      {

      this->m_eScheme=SCHEME_INVALID;

      return;

      }

      }

      this->m_eScheme=SCHEME_INVALID;

      return;

      }

      //解析是不是HTTP協(xié)議的URL,不是返回FALSE,否則進(jìn)一步解析URL對(duì)應(yīng)的協(xié)議名稱,主機(jī)號(hào),端口號(hào),請(qǐng)求資源賦值給成員變量,最后返回TRUE

      bool CUrl::ParseUrlEx(string strUrl)

      {

      char protocol[10];

      char host[HOST_LEN];

      char request[256];

      int  port=-1;

      memset(protocol,0,sizeof(protocol));

      memset(host,0,sizeof(host));

      memset(request,0,sizeof(request));

      this->ParseScheme(strUrl.c_str());//得到協(xié)議類型

      if(this->m_eScheme!=SCHEME_HTTP)//我們只抓取所有協(xié)議名為HTTP的WEB網(wǎng)頁(yè)

      return false;

      ParseUrlEx(strUrl.c_str(),protocol,sizeof(protocol),host,sizeof(host),request,sizeof(request),&port);

      m_sUrl=strUrl;

      m_sHost=host;

      m_sPath=request;

      if(port>0)

      m_nPort=port;

      return true;

      }

      //真正的解析URL的函數(shù)

      void CUrl::ParseUrlEx(const char *url,char *protocol,int lprotocol,char *host,int lhost,char *request,int lrequest,int *port)

      {

      char *ptr,*ptr2,*work;

      *protocol=*host=*request=0;

      *port=DEFAULT_HTTP_PORT;

      int len=strlen(url);

      work=new char[len+1];

      memset(work,0,len+1);

      strncpy(work,url,len);

      ptr=strchr(work,':');//查找work字符串中首次出現(xiàn)':'的位置指針

      //得到協(xié)議名稱

      if(ptr!=NULL)

      {

      *(ptr++)=0;

      strncpy(protocol,work,lprotocol);

      }

      else

      {

      strncpy(protocol,"HTTP",lprotocol);

      ptr=work;

      }

      //跳過(guò)"http://"字符

      if((*ptr=='/')&&(*(ptr+1)=='/'))

      ptr+=2;

      ptr2=ptr;

      while(IsValidHostChar(*ptr2)&&*ptr2)

      ptr2++;

      *ptr2=0;

      //得到主機(jī)號(hào)

      strncpy(host,ptr,lhost);

      int offset=ptr2-work;

      const char *pStr=url+offset;

      //得到請(qǐng)求資源

      strncpy(request,pStr,lrequest);

      ptr=strchr(host,':');

      //得到端口號(hào)

      if(ptr!=NULL)

      {

      *ptr=0;//不能小看這個(gè)地方,很有用,將主機(jī)號(hào)+端口號(hào)相分離

      *port=atoi(ptr+1);

      }

      delete []work;

      work=NULL;

      }

      //無(wú)參構(gòu)造函數(shù)

      CUrl::CUrl()

      {

      this->m_sUrl="";

      this->m_eScheme=SCHEME_INVALID;

      this->m_sHost="";

      this->m_sPath="";

      this->m_nPort=DEFAULT_HTTP_PORT;

      }

      //析構(gòu)函數(shù)

      CUrl::~CUrl()

      {

      }

      //通過(guò)主機(jī)號(hào)得到IP字符串

      char *CUrl::GetIpByHost(const char *host)

      {

      if(!host)

      return NULL;

      if(!IsValidHost(host))

      return NULL;

      unsigned long inaddr=0;

      int len=0;

      char *result=NULL;

      inaddr=(unsigned long)inet_addr(host);//將字符串IP轉(zhuǎn)化為32二進(jìn)制的網(wǎng)絡(luò)字節(jié)序

      if(inaddr!=INADDR_NONE)//表示該主機(jī)號(hào)就是用IP地址表示的

      {

      len=strlen(host);

      result=new char[len+1];

      memset(result,0,len+1);

      memcpy(result,host,len);

      return result;

      }

      else//否則,我在DNS緩存中看能否查找該主機(jī)號(hào)對(duì)應(yīng)的IP字符串

      {

      map<string,string>::iterator it=mapCacheHostLookup.find(host);

      if(it!=mapCacheHostLookup.end())//在DNS緩存中查找到了

      {

      const char *strHostIp;

      strHostIp=(*it).second.c_str();

      inaddr=(unsigned long)inet_addr(strHostIp);

      if(inaddr!=INADDR_NONE)

      {

      len=strlen(strHostIp);

      result=new char[len+1];

      memset(result,0,len+1);

      memcpy(result,strHostIp,len);

      return result;

      }//end if

      }//end if

      }//end else

      //通過(guò)上面的方法我們都沒(méi)有查找,這個(gè)時(shí)候我們只能通過(guò)DNS server查找了,這種帶寬的消耗是必要的!

      struct hostent*hp;

      hp=gethostbyname(host);//通過(guò)主機(jī)號(hào)或者說(shuō)是域名得到hostent結(jié)構(gòu),這個(gè)結(jié)構(gòu)包含主機(jī)號(hào)或者說(shuō)域名的很多信息,例如我們要找的IP字符串就在其中

      if(hp==NULL)

      {

      cout<<"url.cpp:   gethostbyname()函數(shù)出錯(cuò)!"<<endl;

      return NULL;

      }

      struct in_addr in;

      bcopy(*(hp->h_addr_list),(caddr_t)&in,hp->h_length);

      char abuf[INET_ADDRSTRLEN];

      //inet_ntop()將32位的二進(jìn)制網(wǎng)絡(luò)字節(jié)序轉(zhuǎn)化為IP字符串

      if(inet_ntop(AF_INET,(void*)&in,abuf,sizeof(abuf))==NULL)

      {

      cout<<"url.cpp:   inet_ntop()函數(shù)出錯(cuò)!"<<endl;

      return NULL;

      }

      else

      {

      pthread_mutex_lock(&mutexCacheHost);//互斥的鎖定函數(shù)

      if(mapCacheHostLookup.find(host)==mapCacheHostLookup.end())

      mapCacheHostLookup.insert(valTypeCHL(host,abuf));//將新得到的主機(jī)號(hào)<-->IP字符串插入DNS緩存中

      pthread_mutex_unlock(&mutexCacheHost);//互斥的解鎖函數(shù)

      }

          len=strlen(abuf);

          result=new char[len+1];

          memset(result,0,len+1);

          memcpy(result,abuf,len);

          return result;

      }

      //判斷該字符是否為構(gòu)成主機(jī)號(hào)的字符

      bool CUrl::IsValidHostChar(char ch)

      {//主機(jī)號(hào)只能是由26個(gè)大小寫字符,所10個(gè)阿拉伯?dāng)?shù)字,以及. : - _構(gòu)造而成

      return (isalpha(ch)||isdigit(ch)||ch=='.'||ch==':'||ch=='_'||ch=='-');

      }

      //判斷該主機(jī)號(hào)是不是有效的主機(jī)號(hào)

      bool CUrl::IsValidHost(const char *host)

      {

      if(!host)//空的主機(jī)號(hào),我們認(rèn)為是無(wú)效的主機(jī)號(hào)

      return false;

      if(strlen(host)<6)//主機(jī)號(hào)長(zhǎng)度小于6,我們認(rèn)為ieshi無(wú)效的主機(jī)號(hào)

      return false;

      unsigned int i;

      for(i=0;i<strlen(host);i++)

      if(!IsValidHostChar(host[i]))

      return false;

      return true;

      }

      //判斷該URL是否訪問(wèn)過(guò)

      bool CUrl::IsVisitedUrl(const char *url)

      {

      if(!url)

      return true;

      CMD5 iMD5;

      iMD5.GenerateMD5((unsigned char*)url,strlen(url));

      string strDigest=iMD5.ToString();

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

      return true;

      return false;

      }

      //判斷該IP字符串是否有效

      bool CUrl::IsValidIp(const char *ip)

      {

      if(ip==NULL)

      return false;

      unsigned long inaddr=(unsigned long)inet_addr(ip);

      if(inaddr==INADDR_NONE)//顯然該IP參數(shù)不是正確的字符串IP

      return false;

      if(mapIpBlock.size()>0)

      {

      map<unsigned long,unsigned long>::iterator pos;

      for(pos=mapIpBlock.begin();pos!=mapIpBlock.end();pos++)

      {

      unsigned long ret;

      ret=inaddr&~((*pos).second);

      if(ret==(*pos).first)

      return true;

      }//end for

      return false;

      }//end if

      return true;

      }

      //判斷該主機(jī)號(hào)是否為外國(guó)主機(jī)號(hào)

      bool CUrl::IsForeignHost(string host)

      {

      if(host.empty())

      return true;

      if(host.size()>HOST_LEN)

      return true;

      unsigned long inaddr=0;

      inaddr=(unsigned long)inet_addr(host.c_str());

      if(inaddr!=INADDR_NONE)//顯然該HOST是用IP字符串表示的,我們認(rèn)為它不是外國(guó)主機(jī)號(hào)

      return false;//目前無(wú)法通過(guò)字符串IP判斷是不是外國(guó)主機(jī)號(hào),所以一律當(dāng)作國(guó)內(nèi)主機(jī)號(hào)

      string::size_type idx=host.rfind('.');

      string tmp;//tmp得到的是主機(jī)號(hào)中的頂級(jí)域名

      if(idx!=string::npos)

      tmp=host.substr(idx+1);

      CStrFun::Str2Lower(tmp,tmp.size());

      //下面10個(gè)頂級(jí)域名是我們能訪問(wèn)的頂級(jí)域名,其他都視為不能訪問(wèn)的

      const char *home_host[]={"cn","com","net","org","info","biz","tv","cc","hk","tw"};

      int home_host_num=10;

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

      if(tmp==home_host[i])

      return false;

      return true;

      }

      //判斷該URL是否為圖片鏈接

      bool CUrl::IsImageUrl(string url)

      {

      if(url.empty())

      return false;

      if(url.size()>URL_LEN)

      return false;

      string::size_type idx=url.rfind('.');

      string tmp;

      if(idx!=string::npos)

      tmp=url.substr(idx+1);

      CStrFun::Str2Lower(tmp,tmp.size());

      const char *image_type[]={"jpg","bmp","gif","jpeg","png","tif","psd"};

      int image_type_num=7;

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

      if(tmp==image_type[i])

      return true;

      return false;

      }

      //目前不知道系統(tǒng)設(shè)計(jì)這個(gè)函數(shù)的作用----我在這里讓它一律返回false

      bool CUrl::IsUnReachedUrl(const char *url)

      {

      return false;

      }

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多