代理IP爬取和验证(快代理&西刺代理)

前言

仅仅伪装网页agent是不够的,你还需要一点新东西

今天主要讲解两个比较知名的国内免费IP代理网站:西刺代理&快代理,我们主要的目标是爬取其免费的高匿代理,这些IP有两大特点:免费,不稳定(至于为什么要爬不稳定的免费的代理,你心里难道没点B+树么,高富帅谁** 过来学爬虫,还爬代理,人家直接买好么~)

目标

给出目标网站,盘它

快代理

  • 代码详情
import ChangIp.GetAgent
import org.jsoup.Jsoup
import org.jsoup.nodes.Document

import scala.collection.mutable.ArrayBuffer
import scala.util.{Failure, Random, Success, Try}
import scala.collection.JavaConverters._

/**
  * @Author *******
  * @Create 2019-01-23 11:59
  * @Descripation:
  *
  *
  */
object IP_CollectTest {

  //抓取快代理前10页的ip
  def requestGetUrl(times:Int=20)(url:String,tag:String,arr_all:ArrayBuffer[String]): Unit ={
    //设置随机间隔时间
    var delay:Long=500
    delay = (1000+(new Random).nextInt(4000)).toLong

    //开始抓取
    //GetAgent.get_agent()方法--见上一篇,很简单,自己加一下就行
    Try(Jsoup.connect(url+tag).userAgent(GetAgent.get_agent()).get())match {
      case Failure(e) =>{
        if(times!=0){
          println(e.getMessage)
          //抓取失败重试
          Thread.sleep(delay)
          requestGetUrl(times-1)(url,tag,arr_all)
        }else throw e
      }
      case Success(doc) =>
        // 解析网页传入参数,doc和保存数据的数组
        val count = parseDoc(doc,arr_all)
        if (count==0){
          //抓取失败重试
          Thread.sleep(delay)
          if(times>=0){
            requestGetUrl(times-1)(url,tag,arr_all)
          }
          else {
            println(tag+"scrape data failed...,Please comfirm this word again")
          }
        }
    }
  }

  //网页解析
  def parseDoc(doc:Document,arr_all:ArrayBuffer[String]): Int ={
    // 用count判断是否有返回数据
    var count = 0
    val links = doc.select("tr")
    for(link<-links.asScala){
      // 爬取IP
      val ip = link.select("td").select("[data-title=IP]").text()
      // 爬取port
      val port = link.select("td").select("[data-title=PORT]").text()
      // 拼成字符串并保存
      if(!ip.isEmpty && !port.isEmpty){
        val res = ip+":"+port
        println(res)
        arr_all.append(res)
        // 有返回数据则count+1
        count+=1
      }
    }
    count
  }

  def use : ArrayBuffer[String] ={
    // 用一个array数组保存结果
    val arr_all = ArrayBuffer[String]()
    //遍历前10页
    for(i<-Range(1,11)){
      val url = "https://www.kuaidaili.com/free/inha/"
      // 传入三个参数(地址,页数,数组)
      requestGetUrl()(url,i.toString,arr_all)
    }
    //返回保存爬取数据的数组
    arr_all
  }

  def main(args: Array[String]): Unit = {
    use
  }
}

  • 结果展示


西刺代理

这里我们只放一下网页解析的代码,其他的跟上面一样

  • 代码详情
bject XiCi_IPCollect {
  def main(args: Array[String]): Unit = {
    // 爬取的网址
    val url = "https://www.xicidaili.com/nn/1"
    // 加上TryCatch框架
    Try(Jsoup.connect(url).get())match {
      case Failure(e) =>
        // 打印异常信息
        println(e.getMessage)
      case Success(doc:Document) =>
        // 解析正常则返回Document,然后提取Document内所需信息
        val links = doc.select("table#ip_list").select("tr")
        for(link<-links.asScala){
          val txt = link.text()
          val ip = txt.split(" ")(0)
          val port = txt.split(" ")(1)
          if(ip.contains(".")){
            println(ip+":"+port)
          }

        }
    }
  }
}

  • 结果展示


代理验证

因为这些免费IP不稳定的原因,其实这些IP里有很大一部分是不能用的,所以需要我们来提取能用的IP,以节省后续爬虫的时间

验证IP是否可用其实非常简单,就是在header里加入要查询的IP,然后访问一下网站,如果成功,那么代表IP可用

def is_pass(arr_all:ArrayBuffer[String]): ArrayBuffer[String]  = {
    //arr_all 数组里保存这上面我们爬取的代理IP
    val arr_pass = ArrayBuffer[String]()
    for (i <- arr_all) {
      try{
        //proxy(ip,port)这个函数添加ip进header
        val response = Jsoup.connect("http://www.baidu.com").proxy(i.split(":").head.trim,i.split(":").last.trim.toInt).userAgent(agent).execute()
        //网站返回码不是200就可以,这方面有兴趣可以自己google一下
        if(response.statusCode()!=200){
          println("Bad proxy: "+i)
        }
        else {
          arr_pass.append(i)
          println("Success  proxy: "+i)
        }

      }
      catch{
        case e => println(e)
      }

    }
    arr_pass
  }

或者不用简单直接一点

 //验证ip是否可用
  def is_pass(arr_all:ArrayBuffer[String]): ArrayBuffer[String]  ={
    val arr_pass = ArrayBuffer[String]()
    for(i<-arr_all){
      Try(Jsoup.connect(URL_pas).proxy(i.split(":").head.trim,i.split(":").last.trim.toInt).userAgent(agent).get())match {
        case Failure(e)=>
          println(e)
         //如果没有异常,直接添加
        case Success(doc:Document)=>
          //          println(i)
          arr_pass.append(i)
      }
    }
    arr_pass
  }

结尾唠叨两句

如果你对我的文章感兴趣,欢迎你点开我下一篇文章,后面我将手把手带你一起完成一个个小case,对了如果你也有好的想法,欢迎沟通交流
今天主要是分享了一下IP代理获取的小方法,有兴趣的同学还可以自己添加定时的功能,每天更新IP。

posted @ 2019-01-25 14:36 wxplmm 阅读(...) 评论(...) 编辑 收藏