Jsoup-简单爬取知乎推荐页面(附:get_agent())

总览

今天我们就来小用一下Jsoup,从一个整体的角度来看一看爬虫

一个基本的爬虫框架包括:

  • [x] 解析网页
  • [x] 失败重试
  • [x] 抓取内容保存至本地
  • [x] 多线程抓取

    ***

    分模块讲解

    将上述基本框架的模块按逻辑顺序讲解,一步一步复现代码实现过程

  • 失败重试

    一个好的模块必然有异常捕捉和处理

在之前的内容中,我们提到过一个简单的异常处理,小伙伴还记得么

简易版

    // 爬取的网址
    val url = "https://www.zhihu.com/explore/recommendations"
    // 加上TryCatch框架
    Try(Jsoup.connect(url).get())match {
      case Failure(e) =>
        // 打印异常信息
        println(e.getMessage)
      case Success(doc:Document) =>
        // 解析正常则返回Document,然后提取Document内所需信息
        println(doc.body())
    }

今天我们来在之上稍微丰富一下,把他包装的更健壮一点

丰富版

   var count = 0    //解析网页时统计抓取数用
  //用于记录总数,和失败次数
  val sum, fail: AtomicInteger = new AtomicInteger(0)
  //当出现异常时1s后重试,异常重复100次
  def requestGetUrl(times:Int=100,delay:Long=1000) : Unit ={
    Try(Jsoup.connect(Url).userAgent(get_agent()).get())match {
 case Failure(e) =>{
        if(times!=0){
          println(e.getMessage) //打印错误信息
          Thread.sleep(delay) //等待1s
          fail.addAndGet(1) //失败次数+1
          requestGetUrl(times-1,delay)  //times-1后,重调方法
        }else throw e
      }
      case Success(doc) =>
        parseDoc(doc)
        if (count==0){  // 解析网页时用来统计是否抓取为空
          Thread.sleep(delay)
          requestGetUrl(times-1,delay)
        }
        sum.addAndGet(1)  //成功次数+1
    }
  }
  • get_agent()说明
  //自己设置一下user-agent,或者更好的是,可以从一系列的user-agent里随机挑出一个符合标准的使用
  def get_agent()={
  //模拟header的user-agent字段,返回一个随机的user-agent字典类型的键值对
    val agents=Array("Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;",
      "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv,2.0.1) Gecko/20100101 Firefox/4.0.1",
      "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)",
      "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; en) Presto/2.8.131 Version/11.11",
      "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11")
    val ran = new Random().nextInt(agents.length)
    agents(ran)
  }

  • 解析网页

    沿用上一篇我们写过的方法就可以

  //解析Document
  var count = 0
  //用一个hashmap来保存住区的内容
  val text = new ConcurrentHashMap[String,String]()
  def parseDoc(doc:Document): Unit ={
    // 解析正常则返回Document,然后提取Document内所需信息
    val links = doc.select("div.zm-item") //选取class为"zm-item"的div
    for (link<-links.asScala) { //遍历每一个这样的div
      val title = link.select("h2").text() //选取div中的所有"h2"标签,并读取它的文本内容
      val approve = link.select("div.zm-item-vote").text() //找到赞同的位置,选中它并读取它的文本内容
      //逐层找到唯一识别的标签,然后选中(唯一识别很关键)
      val author = link.select("div.answer-head").select("span.author-link-line").select("a").text()
      val content = link.select("div.zh-summary.summary.clearfix").text() //多个class类型,直接加.就行,如.A.B.C

      text.put(title,author+"\t"+approve+"\t"+content)
      count+=1
    }
    count
  }

  • 抓取内容保存至本地
  // 获取当前日期
  def getNowDate(): String ={
    new SimpleDateFormat("yyMMdd").format(new Date())
  }

  // 爬取内容写入文件
  def output(zone:String): Unit ={
    val writer = new PrintWriter(new File(getNowDate()+"_"+zone++".txt"))
    for((title,value)<-text){
      writer.println(title+value)
    }
    writer.flush()
    writer.close()
  }

抓取内容展示


  • 多线程抓取
  //多线程抓取
  def concurrentCrawler(zone: String,maxPage:Int,threadNum:Int)={
    var loopar = (1 to maxPage).par
    loopar.tasksupport = new ForkJoinTaskSupport(new ForkJoinPool(threadNum))
    loopar.foreach(x=>requestGetUrl())
    output(zone)
  }

  • get_agent()补充说明及福利
def get_agent()={
    //模拟header的user-agent字段,返回一个随机的user-agent字典类型的键值对
    val agents=Array("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",
      "Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11",
      "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6",
      "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6",
      "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1",
      "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5",
      "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5",
      "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
      "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
      "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
      "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
      "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
      "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
      "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
      "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
      "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3",
      "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24",
      "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24",
      "Mozilla/5.0 (Macintosh; U; Mac OS X Mach-O; en-US; rv:2.0a) Gecko/20040614 Firefox/3.0.0 ",
      "Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10.5; en-US; rv:1.9.0.3) Gecko/2008092414 Firefox/3.0.3",
      "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1) Gecko/20090624 Firefox/3.5",
      "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.14) Gecko/20110218 AlexaToolbar/alxf-2.0 Firefox/3.6.14",
      "Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10.5; en-US; rv:1.9.2.15) Gecko/20110303 Firefox/3.6.15",
      "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1",
      "Mozilla/5.0(Macintosh;U;IntelMacOSX10_6_8;en-us)AppleWebKit/534.50(KHTML,likeGecko)Version/5.1Safari/534.50")
    val ran = new Random().nextInt(agents.length)
    agents(ran)
  }

结尾唠叨两句

如果你对我的文章感兴趣,欢迎你点开我下一篇文章,后面我将手把手带你一起完成一个个小case,对了如果你也有好的想法,欢迎沟通交流

今天主要是带大家一起完成了知乎网站的爬取,练一练手,熟能生巧!

原文地址:https://www.cnblogs.com/wxplmm/p/10308774.html

时间: 2024-10-09 22:42:12

Jsoup-简单爬取知乎推荐页面(附:get_agent())的相关文章

python scrapy简单爬虫记录(实现简单爬取知乎)

之前写了个scrapy的学习记录,只是简单的介绍了下scrapy的一些内容,并没有实际的例子,现在开始记录例子 使用的环境是python2.7, scrapy1.2.0 首先创建项目 在要建立项目的目录下执行命令scrapy startproject tutorial scrapy会帮你建立好项目,接着创建蜘蛛scrapy genspider zhuhuSpider zhihu.com 当前的文件结构是 --tutorial --spiders --__init__.py --zhihuSpid

scrapy 爬取知乎问题、答案 ,并异步写入数据库(mysql)

  python版本  python2.7 爬取知乎流程: 一 .分析 在访问知乎首页的时候(https://www.zhihu.com),在没有登录的情况下,会进行重定向到(https://www.zhihu.com/signup?next=%2F)这个页面, 爬取知乎,首先要完成登录操作,登陆的时候观察往那个页面发送了post或者get请求.可以利用抓包工具来获取登录时密码表单等数据的提交地址. 1.利用抓包工具,查看用户名密码数据的提交地址页就是post请求,将表单数据提交的网址,经过查看

爬虫---Beautiful Soup 爬取知乎热榜

前两章简单的讲了Beautiful Soup的用法,在爬虫的过程中相信都遇到过一些反爬虫,如何跳过这些反爬虫呢?今天通过豆瓣网写一个简单的反爬中 什么是反爬虫 简单的说就是使用任何技术手段,阻止别人批量获取自己网站信息的一种方式.关键也在于批量. 反反爬虫机制 增加请求头---headers为了模拟更真实的用户场景 更改IP地址---网站会根据你的IP对网站访问频密,判断你是否属于爬虫 ua限制---UA是用户访问网站时候的浏览器标识,其反爬机制与ip限制类似 模拟帐号登录----通过reque

python——关于简单爬取博客园班级成员发的博文的题目、发布人、阅读、评论,再存到csv文件中

因为老师要以班里每个人发的博客质量作为最后总成绩的评定的一部分,就要把班上所有同学发的博客都统计起来,可以用来评定的因素有:阅读.评论.推荐等,但因为今天只是做一个简单的爬取,推荐这个元素在班级博客中需要点开每一篇博文才能看到获取,就不爬取了,只爬取阅读和推荐,加上每篇博文的发布人和标题. 我先会放上代码,再逐条解释其含义及作用. 代码如下(其中爬取的网页是以我自己的班级为例): 1 from bs4 import BeautifulSoup 2 import pandas as pd 3 im

Python爬虫爬取知乎小结

博客首发至Marcovaldo's blog (http://marcovaldong.github.io/) 最近学习了一点网络爬虫,并实现了使用python来爬取知乎的一些功能,这里做一个小的总结.网络爬虫是指通过一定的规则自动的从网上抓取一些信息的程序或脚本.我们知道机器学习和数据挖掘等都是从大量的数据出发,找到一些有价值有规律的东西,而爬虫则可以帮助我们解决获取数据难的问题,因此网络爬虫是我们应该掌握的一个技巧. python有很多开源工具包供我们使用,我这里使用了requests.Be

利用 Scrapy 爬取知乎用户信息

思路:通过获取知乎某个大V的关注列表和被关注列表,查看该大V和其关注用户和被关注用户的详细信息,然后通过层层递归调用,实现获取关注用户和被关注用户的关注列表和被关注列表,最终实现获取大量用户信息. 一.新建一个scrapy项目 scrapy startproject zhihuuser 移动到新建目录下: cd zhihuuser 新建spider项目: scrapy genspider zhihu 二.这里以爬取知乎大V轮子哥的用户信息来实现爬取知乎大量用户信息. a) 定义 spdier.p

爬取知乎Python中文社区信息

爬取知乎Python中文社区信息,https://zhuanlan.zhihu.com/zimei 1 import requests 2 from urllib.parse import urlencode 3 from pyquery import PyQuery as pq 4 from pymongo import MongoClient 5 import json 6 import time 7 8 base_url = 'https://www.zhihu.com/api/v4/co

爬取知乎热榜标题和连接 (python,requests,xpath)

用python爬取知乎的热榜,获取标题和链接. 环境和方法:ubantu16.04.python3.requests.xpath 1.用浏览器打开知乎,并登录 2.获取cookie和User-Agent 3.上代码 1 import requests 2 from lxml import etree 3 4 def get_html(url): 5 headers={ 6 'Cookie':'', 7 #'Host':'www.zhihu.com', 8 'User-Agent':'Mozill

02. 爬取get请求的页面数据

目录 02. 爬取get请求的页面数据 一.urllib库 二.由易到难的爬虫程序: 02. 爬取get请求的页面数据 一.urllib库 urllib是Python自带的一个用于爬虫的库,其主要作用就是可以通过代码模拟浏览器发送请求.其常被用到的子模块在Python3中的为urllib.request和urllib.parse,在Python2中是urllib和urllib2. 二.由易到难的爬虫程序: 1.爬取百度首页面所有数据值 1 #!/usr/bin/env python 2 # -*