golang如何实现抓取IP地址的蜘蛛程序详解

  


  

  

要做IP地址归属地查询,量比较大,所以想先从网上找到大部分的分配数据,写个蜘蛛程序来抓取入库,以后在程序的运行中不断进行维护,更新,完善。

  


  

  
      <李> goroutine的使用,让程序并行运行。   <李>正则表达式分组信息提取的使用,正确的提取我们关注的信息。   <李>数据库批量插入操作。   <李>数据库批量更新操作。   
  


  

  

按功能模块对核心代码进行说明

  

ip。去
  

  

主进程,实现goroutine的调用。
  

        函数main () {//利用去基本库封装的网页抓取函数,后面有说明   ctx:=common.HttpGet (“http://ips.chacuo.net/?//正则表达式,有两个分组(两组小括号),分别取城市信息与url,具体分析代码后面有说明   注册:=regexp.MustCompile (& lt; li> & lt;一个标题=" [\ S] + " href=' https://www.yisu.com/zixun/([^] + & # 63;)的祝辞([^ & lt;] + & # 63;) & lt;/a> & lt;/li>”)//取得页面上所有的城市及相应的url   “诱导多能性”:=reg.FindAllStringSubmatch(字符串(ctx), 1)      陈ch:=(字符串)//建立无缓冲字符串通道      _,el:=范围ips{//一个协程处理一个具体页面   ipSpider去。SpiderOnPage (el [1], [2], ch)   }      用于范围ips{//阻塞等待所有抓取工作全部完成   fmt.Println (& lt; ch)   }   }      

<强>正则表达式说明
  

  

主进程针对所有省有入口页面,取得每省的入口分配给一个协程去处理,每一个入口是这个样子
  

        & lt;一个标题="北京最新IP地址段" href=" http://ips.chacuo.net/view/s_BJ " rel=巴獠縩ofollow”在北京& lt;/a>      
      <李>请注意,这里面变化只有三个部分(标题内容,href内容,链接显示内容),其中两个部分是我们需要的李   <李>标题内容对应正则为[\ S] +,非空白符   <李> href内容对应的正则为([^]+ & # 63;),第一次遇到单引号结束,问号表示非贪婪匹配,括号是分组,能方便取出所匹配信息李   <李>链接显示内容对应的正则为([^ & lt;] + & # 63;),第一次遇到& lt;时结束,第二个分组   <李> FindAllStringSubmatch函数可以取出所有子分组,子分组从下标1开始,0为正则整体匹配的字符串李   
  

<强> goroutine流程
  

  
      <李>建立一个无缓冲字符串通道,作为所有协程与主进程通信通道李   <李>循环正则匹配结果,为每一个省的页面分配一个协程李   <李>协程获取数据成功并批量写数据库,返回成功信息到通道李   <李>协程处理失败,反回失败信息到通道李   <李>主进程阻塞等所有协程成功或失败返回,并打印成功或失败信息李   
  


  

  

与主进程类似,注意无信息时处理。
  

  

IpSpider.go      //获取页面数据   ctx:=common.HttpGet (url)//注册:=regexp.MustCompile (' & lt; li> & lt;一个标题=" [\ S] + " href=' https://www.yisu.com/zixun/([^] + & # 63;)的祝辞([^ & lt;] + & # 63;) & lt;/a> & lt;/li>”)//两个分组分别对应的IP段开始与结束   reg:=regexp.MustCompile (' & lt; dd> & lt;跨类=皏_l祝辞([^ & lt;] + & # 63;) & lt;/span> & lt;跨类=皏_r祝辞([^ & lt;] + & # 63;) & lt;/span> & lt; div类=癱learfix祝辞& lt;/div> & lt;/dd>”)//& lt; dd> & lt;跨类=皏_l祝辞49.64.0.0 & lt;跨类=皏_r祝辞49.95.255.255 & lt; div类=癱learfix祝辞& lt;/div> & lt;/dd>//取得所有匹配的分组信息   知识产权:=reg.FindAllStringSubmatch(字符串(ctx), 1)//没有取得任何信息,提前返回,很重要,不然主进程会一直等待结束不了   如果len (ip)==0 {   ch & lt;——“没有数据存在。”   返回nil   }      

数据库表结构生成语句
  

        创建表“ip_addr_info”(   “id”int (11) NOT NULL AUTO_INCREMENT评论“索引、自动增长”,   ip_addr_begin varchar (32) NOT NULL默认”评论“ip地址段开始”,   ip_addr_end varchar(32)默认”评论“ip地址段结束”,   ‘省’varchar(32)默认的“评论”所属省”,   ip_comp varchar(32)默认”评论“运营商”,   主键(“id”),   唯一键“ip_addr”(“ip_addr_begin”、“ip_addr_end”)   )引擎=InnoDB AUTO_INCREMENT=7268默认字符集=utf8评论=怼?

golang如何实现抓取IP地址的蜘蛛程序详解