总览

今天我们就来小用一下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,对了如果你也有好的想法,欢迎沟通交流

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

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

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

    之前写了个scrapy的学习记录,只是简单的介绍了下scrapy的一些内容,并没有实际的例子,现在开始记录例子 使用的环境是python2.7, scrapy1.2.0 首先创建项目 在要建立项目的目 ...

  2. 一个简单的python爬虫,爬取知乎

    一个简单的python爬虫,爬取知乎 主要实现 爬取一个收藏夹 里 所有问题答案下的 图片 文字信息暂未收录,可自行实现,比图片更简单 具体代码里有详细注释,请自行阅读 项目源码: # -*- cod ...

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

      python版本  python2.7 爬取知乎流程: 一 .分析 在访问知乎首页的时候(https://www.zhihu.com),在没有登录的情况下,会进行重定向到(https://www. ...

  4. python 爬取知乎图片

    先上完整代码 import requests import time import datetime import os import json import uuid from pyquery im ...

  5. 通过scrapy,从模拟登录开始爬取知乎的问答数据

    这篇文章将讲解如何爬取知乎上面的问答数据. 首先,我们需要知道,想要爬取知乎上面的数据,第一步肯定是登录,所以我们先介绍一下模拟登录: 先说一下我的思路: 1.首先我们需要控制登录的入口,重写star ...

  6. Golang+chromedp+goquery 简单爬取动态数据

    目录 Golang+chromedp+goquery 简单爬取动态数据 Golang的安装 下载golang软件 解压golang 配置golang 重新导入配置 chromedp框架的使用 实际的代 ...

  7. 教程+资源,python scrapy实战爬取知乎最性感妹子的爆照合集(12G)!

    一.出发点: 之前在知乎看到一位大牛(二胖)写的一篇文章:python爬取知乎最受欢迎的妹子(大概题目是这个,具体记不清了),但是这位二胖哥没有给出源码,而我也没用过python,正好顺便学一学,所以 ...

  8. python scrapy爬取知乎问题和收藏夹下所有答案的内容和图片

    上文介绍了爬取知乎问题信息的整个过程,这里介绍下爬取问题下所有答案的内容和图片,大致过程相同,部分核心代码不同. 爬取一个问题的所有内容流程大致如下: 一个问题url 请求url,获取问题下的答案个数 ...

  9. 使用python scrapy爬取知乎提问信息

    前文介绍了python的scrapy爬虫框架和登录知乎的方法. 这里介绍如何爬取知乎的问题信息,并保存到mysql数据库中. 首先,看一下我要爬取哪些内容: 如下图所示,我要爬取一个问题的6个信息: ...

随机推荐

  1. Java 中抽象类与接口的区别

    TypeScript 中的接口,有点类似抽象类的概念.Java 中抽象类属于包含属性与抽象行为,而接口通常只是抽象行为.抽象类可以实现模板模式. 参考 https://www.cnblogs.com/ ...

  2. 关于WAMP的apache 人多了就访问非常卡的问题解决方法

    一直用WAMP 但人多了(在线人数上了500) 就卡得不得了 而这时服务器负载却很小 CPU15% 内存25% 整了好久都没个结果 偶然看到一篇教程 原来是连接数限制的问题 改了就速度飞快了 打开ap ...

  3. Vue之nextTick()

    我们有时候操作 DOM,是想在 data 数据变更的时候进行操作. 那么,我们应该怎么做呢? index.html <!DOCTYPE html> <html lang=" ...

  4. vscode 输出面板字符编码问题

    默认的输出中文会显示成乱码,需要在vscode内部的终端中输入 chcp 65001 缺点是需要每次打开vscode进行激活,另一种方式是在vscode的首选项中进行配置: "termina ...

  5. CSP模拟赛 Lost My Music(二分,可回退化栈)

    题面 题解 发现是斜率的形式,答案的相反数可以看做一条直线的斜率.那么我们要答案最小,斜率最大.维护下凸壳就行了. 考试时写了直接dfsdfsdfs+暴力弹栈拿了808080分(还以为自己是O(n)正 ...

  6. VIM--保存和退出等命令

    在 Linux 中使用 vim 时,输入 vim xxx.file 按 ESC,左下角就可以进行输入 :w 保存但不退出 :wq 保存并退出 :q 退出 :q! 强制退出,不保存 :e! 放弃所有修改 ...

  7. 【HTTP】协议详解

    什么是HTTP协议 协议是指计算机通信网络中两台计算机之间进行通信所必须共同遵守的规定或规则,超文本传输协议(HTTP)是一种通信协议,它允许将超文本标记语言(HTML)文档从Web服务器传送到客户端 ...

  8. vscode搭建springboot开发环境

    1. JDK,Maven 1.1 下载略 1.2 设置系统环境变量 jdk增加环境变量JAVA_HOME=C:\Program Files\Java\jdk1.8.0_191(安装路径) 增加路径Pa ...

  9. MongoDB下载不了的问题

    官网上,mongoDB数据库下载不了,搜了半天,在知乎上找到答案:在MongoDB download center中选择community-server,拖到底部有一个all versions bin ...

  10. 通过AS提交AndroidLibrary到JCenter仓库

    注意事项: //版本需要一致,如下版本对应gradle-4.4-all.zip dependencies { classpath 'com.android.tools.build:gradle:3.1 ...