**

jsoup爬虫实战详解之新浪

**
今天分享一个之前困扰了一段时间的关于jsoup爬取新浪网页信息的踩坑总结。
在实现以上功能的之前我门首先要了解两个重点:1.关于jsoup的爬取细节以及教程,爬取时所要了解jsoup的相关标签:具体的自己大家感兴趣的可以自行百度去详细了解下对应的教程。
2.第二点就是我们要了解爬取对面网站的页面构造,现在大体分为HTML形式的展示,还有一种是通过js异步加载所呈现页面效果的形式,js异步加载相对而言比较复杂,今天我们着重讲解下以html形式展示的jsoup实战使用,今天就以新浪为网页为例子进行讲解。

第一步:引入相应的pom文件内容:

第二步:了解新浪网页的基础的构造

我们进入新浪网页,例如我们点进到体育分类栏,进入体育分类页面右击查看网页源码,我们可以看到

对应的列表的构造基本是ul>li>a,我们就可以获取到对应标题进入详情的链接
上述我们可以获取对应分类的列表信息,我们随便点一个进入到对应的详情页面继续看下页面的构造情况:

对应的详情的基本结构就是以class为article为主导的基本数据的构造。今天我门就基本讲解将对应的标题内容信息进行抓取为功能的主导实现
上述就是新浪的对应的页面构造,下面我们直接进入业务代码:

1.通过模拟CHROME览器来获取页面的document信息,代码如下

url为对应的抓取的对应的路径信息,useHtmlUnit为是否使用HtmlUnit此处我们可以传值为false。

    public static Document getHtmlFromUrl(String url, boolean useHtmlUnit) {Document document = null;if (!useHtmlUnit) {try {document = Jsoup.connect(url)// 模拟火狐浏览器.userAgent("Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)").get();} catch (Exception e) {}} else {// 模拟CHROME览器WebClient webClient = new WebClient(BrowserVersion.CHROME);webClient.getOptions().setJavaScriptEnabled(true);// 1 启动JSwebClient.getOptions().setCssEnabled(false);// 2 禁用Css,可避免自动二次请求CSS进行渲染webClient.getOptions().setActiveXNative(false);webClient.getOptions().setRedirectEnabled(true);// 3 启动重定向webClient.setCookieManager(new CookieManager());// 4 启动cookie管理webClient.setAjaxController(new NicelyResynchronizingAjaxController());// 5 启动ajax代理webClient.getOptions().setThrowExceptionOnScriptError(false);// 6 js运行错误时,是否抛出异常webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);webClient.getOptions().setUseInsecureSSL(true);// 忽略ssl认证webClient.getOptions().setTimeout(10000);// 7 设置超时/*** 设置代理 ProxyConfig proxyConfig = webClient.getOptions().getProxyConfig(); proxyConfig.setProxyHost(listserver.get(0));* proxyConfig.setProxyPort(Integer.parseInt(listserver.get(1)));*/HtmlPage htmlPage = null;try {htmlPage = webClient.getPage(url);webClient.waitForBackgroundJavaScript(10000);webClient.setJavaScriptTimeout(10000);String htmlString = htmlPage.asXml();return Jsoup.parse(htmlString);} catch (Exception e) {e.printStackTrace();} finally {webClient.close();}}return document;}

第二步核心代码

 /*** * @param: @param 对应抓取的路径信息:http://sports.sina.com.cn/假定新浪的体育路径* @param: @param 对应标签id 自己的对应的标签id,此处代表新浪* @param: @param 上线数* @param: @param 对应网页的标签规则:此处我们假定为:ul > li > a* @param: @return 数量标签如果为0则爬取结束   * @return: List<Map<String,String>>*/private static List<Map<String,String>> pullNews(String tagUrl,Integer tag,Integer num,String regex) {//获取网页Document html= null;try {html = BaseJsoupUtil.getHtmlFromUrl(tagUrl, false);} catch (Exception e) {}List<Map<String,String>> returnList = new ArrayList<>();//定义返回的list//jsoup获取<a>标签,不同的地址匹配不同的匹配规则Elements newsATags = null;//可以理解为上述的,上述我们关于体育的第一个页面的规则基本为:ul > li > aif(Utils.notBlank(regex)) {newsATags = html.select(regex);}else {System.out.println(tagUrl+"采集规则未设置");return returnList;}//当规则不适用时if(newsATags.isEmpty()) {System.out.println(tagUrl+"规则不适用");return returnList;}//从<a>标签中抽取urlList<Map<String,String>> list = new ArrayList<>();//定义存储url的list//遍历我们体育专题的列表信息来获取通过对应的url获取对应的详情信息for (Element a : newsATags) {String articleTitle=a.text();//获取当前标题信息String url = a.attr("href");//获取对应的标题的路径,也就是我上述所说的跳转对应详情的路径,我们通过进入详情来抓取我们想要的文章标题,图片等信息if(url.contains("html")) {if(url.indexOf("http") == -1) {url = "http:" + url;}Map<String,String> map = new HashMap<>();map.put("url", url);map.put("title", articleTitle);list.add(map);}else {continue;  }      }//根据url访问页面获取内容for(Map<String,String> m :list) {Document newsHtml = null;try {//通过模拟器获取对应路径下的html信息,此处的url就是对应的详情的链接,通过模拟器获取对应的页面信息内容newsHtml = BaseJsoupUtil.getHtmlFromUrl(m.get("url"), false);String title=m.get("title");//获取标题Elements newsContent=null;String data;newsContent=newsHtml.select(".article");//这里就是我上述讲解信息的第二个说的jsoup通过标签来进行信息抓取,上述的为class为article的抓取规则if(newsContent!=null) {      String content=newsContent.toString();//获取对应的内容信息//篇幅太短的文章不需要if(content.length() < 200) {//过滤过长的文章break;}//时间过滤if(Utils.isBlank(newsHtml.select(".date").text())) {data=newsHtml.select(".time").text().replaceAll("年", "-").replaceAll("月", "-").replaceAll("日", "");}else{data=newsHtml.select(".date").text().replaceAll("年", "-").replaceAll("月", "-").replaceAll("日", "");}//指定路径时间过滤if(tagUrl.equals("http://collection.sina.com.cn/")) {data=newsHtml.select(".titer").text().replaceAll("年", "-").replaceAll("月", "-").replaceAll("日", "");}else if(tagUrl.equals("https://finance.sina.com.cn/stock/") || tagUrl.equals("http://blog.sina.com.cn/lm/history/")) {data=newsHtml.select(".time SG_txtc").text().replaceAll("年", "-").replaceAll("月", "-").replaceAll("日", "").replaceAll("(", "").replaceAll(")", "");}//获取到图片信息List<String> imgSrcList = BaseJsoupUtil.getImgSrcList(content);String coverImg = "";if(!imgSrcList.isEmpty()) {if(num == 0) {break;//已达设定的采集数量上限}num --;for(String url : imgSrcList){String imgUrl = BaseJsoupUtil.downloadUrl(url.indexOf("http") == -1?"http:" + url:url);content = Utils.isBlankStr(content)?content:content.replace(url, imgUrl);if(Utils.isBlank(coverImg))coverImg = imgUrl.replace(FileConst.QINIU_FILE_HOST+"/", "");}//获取到我们想要的东西封装到map里面,这样就基本结束拉Map<String,String> map = new HashMap<>();map.put("title", title);//标题map.put("date", data);//文章创建时间map.put("content", HtmlCompressor.compress(content));//文章内容map.put("tag", tag.toString());//标签idmap.put("coverImg", coverImg);//文章封面图map.put("url", m.get("url"));//urlreturnList.add(map);}}} catch (Exception e) {e.printStackTrace();}}return returnList;}

上述就是jsoup抓取的基本逻辑,整体的总结就是熟悉对应jsoup的标签使用教程,想要抓取页面的具体规则,知道了这些基本就可以结合自己的业务逻辑来进行信息获取,这里关于新浪的抓取我们只做技术交流,希望大家不要用于商业使用。好了,今天就到这里了,后期继续分享自己的踩坑记录,有什么问题的可以留言。

jsoup爬虫实战详解之新浪相关推荐

  1. Python爬虫实战详解:爬取图片之家

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理 如何使用python去实现一个爬虫? 模拟浏览器 请求并获取网站数据 在原始 ...

  2. 使用mdadm创建raid mdadm命令详解_php_sir_新浪博客

    1.虚拟机上添加5块新磁盘 2.fdisk /dev/sdb,添加三个1G的分区,类型设为fd(linux raid autodetect) 3.dd if=/dev/sdb of=/dev/sdx  ...

  3. 《Java和Android开发实战详解》——2.2节构建Java应用程序

    本节书摘来自异步社区<Java和Android开发实战详解>一书中的第2章,第2.2节构建Java应用程序,作者 陈会安,更多章节内容可以访问云栖社区"异步社区"公众号 ...

  4. flutter 获取android 还是ios_Flutter完整开发实战详解(二十、 Android PlatformView 和键盘问题)...

    作为系列文章的第二十篇,本篇将结合官方的技术文档科普 Android 上 PlatformView 的实现逻辑,并且解释为什么在 Android 上 PlatformView 的键盘总是有问题. 为什 ...

  5. 《Android NFC开发实战详解》——6.4节Android NFC P2P开发进阶

    本节书摘来自异步社区<Android NFC开发实战详解>一书中的第6章,第6.4节Android NFC P2P开发进阶,作者 赵波,更多章节内容可以访问云栖社区"异步社区&q ...

  6. 《数据修复技术与典型实例实战详解》——1.4 分区表的修复

    本节书摘来自异步社区<数据修复技术与典型实例实战详解>一书中的第1章,第1.4节,作者:叶润华著,更多章节内容可以访问云栖社区"异步社区"公众号查看 1.4 分区表的修 ...

  7. Flutter完整开发实战详解(二、 快速开发实战篇) | 掘金技术征文

     作为系列文章的第二篇,继<Flutter完整开发实战详解(一.Dart语言和Flutter基础)>之后,本篇将为你着重展示:如何搭建一个通用的Flutter App 常用功能脚手架,快速 ...

  8. 《Android Studio应用开发实战详解》——第1章,第1.4节Android和Linux的关系

    本节书摘来自异步社区<Android Studio应用开发实战详解>一书中的第1章,第1.4节Android和Linux的关系,作者 王翠萍,更多章节内容可以访问云栖社区"异步社 ...

  9. 《Android Studio应用开发实战详解》——第1章,第1.1节移动智能设备系统发展现状...

    本节书摘来自异步社区<Android Studio应用开发实战详解>一书中的第1章,第1.1节移动智能设备系统发展现状,作者 王翠萍,更多章节内容可以访问云栖社区"异步社区&qu ...

  10. SENet实战详解:使用SE-ReSNet50实现对植物幼苗的分类

    摘要 1.SENet概述 ​ Squeeze-and-Excitation Networks(简称 SENet)是 Momenta 胡杰团队(WMW)提出的新的网络结构,利用SENet,一举取得最后一 ...

最新文章

  1. 用python实现微信消息群发和微信自动回复
  2. J2ME下漫游(追逐)AI的实现
  3. 程序员读研如何提高技术之我见
  4. _CRT_SECURE_NO_WARNINGS错误提示,解决办法
  5. [短文速读] a=a+b和a+=b的区别
  6. 《精通移动app测试实战:技术、工具和案例》新书上市
  7. eclipse不能调试运行Android程序问题的解决办法
  8. [BZOJ 2500] 幸福的道路
  9. a卡显存定位软件tserver_不止显卡!这些硬件因素也a影响着你的深度学习模型性能...
  10. Android历史与版本变迁
  11. java中的POJO类
  12. matlab-俄罗斯方块小游戏
  13. Mendix APP在腾讯云部署说明文档
  14. vscode中setting设置
  15. 人生八境——古诗词中读懂人生境界
  16. [BUUCTF-pwn] zer0ptts_2020_protrude
  17. PPT文件不能编辑怎么回事?
  18. 企业为什么要使用云计算,主要有哪些优势?
  19. iphone怎么迁移数据_如何将数据从旧iPhone迁移到新iPhone
  20. matlab 股,用Matlab来做三种股票的投资模型

热门文章

  1. Word转换pdf文件之好用的pdf虚拟打印机
  2. Multisim12使用记录
  3. 面向Web应用的并发压力测试工具——Locust实用攻略
  4. java比较常用的缓存技术_常用缓存技术
  5. lept_json的学习之stringify
  6. IDEA和webstorm破解方式
  7. 看故事也能长知识,CPU的工作原理原来这么简单!
  8. 【SQL Server】用SQL命令建立数据库和表
  9. decimal.JS 快速入门
  10. 基于 HTML5 Canvas 的 3D 热力云图效果