之前是完全不会爬虫的,但是新项目中需要从网页上爬一大堆的数据,所以就花了一天时间学习了下。主题部分还是很简单的。
* 既然想要写博文,那我就要写的细致点,对自己对读者都是一种负责!


什么是爬虫?

我所理解的爬虫就是从互联网上获取Url,顺着Url一个一个的去访问页面
一个页面会有很多的链接,对于每个链接可以判断是否使我们想要的,再对子链接进行操作、访问等等。

for each 链接 in 当前网页所有的链接
{if(如果本链接是我们想要的 || 这个链接从未访问过){处理对本链接把本链接设置为已访问}
}

对于爬虫:
1. 首先你需要给定一个种子链接。
2. 在种子链接当中寻找你要的子链接。
3. 通过子链接访问其他页面,在页面中获取你所需要的内容。

这当中涉及到的内容有:

  1. Http
  2. 内容解析器

其主要的过程是这样的:

  1. 取一个种子URL,比如www.oschina.net

  2. 通过httpclient请求获取页面资源(获取的页面资源其中肯定包含了其他的URL,可以作为下一个种子循环使用)

  3. 通过正则或者jsoup解析出想要的内容(解析出其他的URL链接,同时获取本页面的所有图片,这都是可以的)

  4. 使用3获取的下一个种子URL,重复1


我们先来看下如何用 HttpClient 获取到整个页面:
在使用 HttpClient 之前,你需要先导入 HttpClint.jar 包

在HttpClient jar更新之后,使用的实例都是 CloseableHttpClient 了所以我们也用它

 public static String get(String url){String result = "";try {//获取httpclient实例CloseableHttpClient httpclient = HttpClients.createDefault();//获取方法实例。GETHttpGet httpGet = new HttpGet(url);//执行方法得到响应CloseableHttpResponse response = httpclient.execute(httpGet);try {//如果正确执行而且返回值正确,即可解析if (response != null&& response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {System.out.println(response.getStatusLine());HttpEntity entity = response.getEntity();//从输入流中解析结果result = readResponse(entity, "utf-8");}} finally {httpclient.close();response.close();}}catch (Exception e){e.printStackTrace();}return result;}/*** stream读取内容,可以传入字符格式* @param resEntity* @param charset* @return*/private static String readResponse(HttpEntity resEntity, String charset) {StringBuffer res = new StringBuffer();BufferedReader reader = null;try {if (resEntity == null) {return null;}reader = new BufferedReader(new InputStreamReader(resEntity.getContent(), charset));String line = null;while ((line = reader.readLine()) != null) {res.append(line);}} catch (Exception e) {e.printStackTrace();} finally {try {if (reader != null) {reader.close();}} catch (IOException e) {}}return res.toString();}

通过这种方法,获取到的是整个页面的资源,其中包含了Html的代码(www.baidu.com):

<!DOCTYPE html>
<!--STATUS OK-->
<html><head><meta http-equiv="content-type" content="text/html;charset=utf-8"><meta http-equiv="X-UA-Compatible" content="IE=Edge"><meta content="always" name="referrer"><link rel="stylesheet" type="text/css" href="http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css"><title>百度一下,你就知道</title></head> <body link="#0000cc"> <div id="wrapper"> <div id="head"> <div class="head_wrapper"> <div class="s_form"> <div class="s_form_wrapper"> <div id="lg"> <img hidefocus="true" src="//www.baidu.com/img/bd_logo1.png" width="270" height="129"> </div> <form id="form" name="f" action="//www.baidu.com/s" class="fm"> <input type="hidden" name="bdorz_come" value="1"> <input type="hidden" name="ie" value="utf-8"> <input type="hidden" name="f" value="8"> <input type="hidden" name="rsv_bp" value="1"> <input type="hidden" name="rsv_idx" value="1"> <input type="hidden" name="tn" value="baidu"><span class="bg s_ipt_wr"><input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off" autofocus></span><span class="bg s_btn_wr"><input type="submit" id="su" value="百度一下" class="bg s_btn"></span> </form> </div> </div> <div id="u1"> <a href="http://news.baidu.com" name="tj_trnews" class="mnav">新闻</a> <a href="http://www.hao123.com" name="tj_trhao123" class="mnav">hao123</a> <a href="http://map.baidu.com" name="tj_trmap" class="mnav">地图</a> <a href="http://v.baidu.com" name="tj_trvideo" class="mnav">视频</a> <a href="http://tieba.baidu.com" name="tj_trtieba" class="mnav">贴吧</a> <noscript> <a href="http://www.baidu.com/bdorz/login.gif?login&amp;tpl=mn&amp;u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1" name="tj_login" class="lb">登录</a> </noscript> <script>document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ '" name="tj_login" class="lb">登录</a>');</script> <a href="//www.baidu.com/more/" name="tj_briicon" class="bri" style="display: block;">更多产品</a> </div> </div> </div> <div id="ftCon"> <div id="ftConw"> <p id="lh"> <a href="http://home.baidu.com">关于百度</a> <a href="http://ir.baidu.com">About Baidu</a> </p> <p id="cp">?2017&nbsp;Baidu&nbsp;<a href="http://www.baidu.com/duty/">使用百度前必读</a>&nbsp; <a href="http://jianyi.baidu.com/" class="cp-feedback">意见反馈</a>&nbsp;京ICP证030173号&nbsp; <img src="//www.baidu.com/img/gs.gif"> </p> </div> </div> </div>  </body>
</html>

其中包含了,子链接,文本,图片。这不是我们要的,需要过滤。


正则表达式过滤方法

相信大家都知道正则表达式,在Java中两个类 Pattern 和 Matcher 都是为它服务的。

        String regexStr = "[abdh]e";String targetStr = "hello world";//获取Pattern对象Pattern pattern = Pattern.compile(regexStr);// 定义一个matcher用来做匹配Matcher matcher = pattern.matcher(targetStr);if (matcher.find()) {System.out.println(matcher.group());}

我只是提一下有这个东西,它并不好用。。。所以我们需要用的是Jsoup


Jsoup

使用Jsoup的前提是需要导入对应的包
Jsoup当中已经封装了对应的方法来获取网页当中的内容:

        String url = "http://www.baidu.com";org.jsoup.nodes.Document doc = Jsoup.connect(url).get();

是不是很方便。。。。都在Document中了
而且Jsoup定义了检索的方法,可以遍历文档中的内容

比如你需要的是子链接:

        String url = "http://www.baidu.com";org.jsoup.nodes.Document doc = Jsoup.connect(url).get();Elements links = doc.select("a[href]");System.out.println(links.size());for (org.jsoup.nodes.Element link : links) {System.out.println(link.attr("abs:href") + " " + link.text());}

只需要这么写,在links中得到的就全部都是子链接的筛选结果,并且通过遍历的方式展示出来(我从其他网址抓的内容):


http://www.haodou.com/recipe/839235/  猪蹄花生煲
http://www.haodou.com/recipe/287246/  银耳陈皮生姜炖梨
http://www.haodou.com/recipe/160157/  心太软
http://www.haodou.com/recipe/260392/  韩式蜂蜜大枣茶
http://www.haodou.com/recipe/296090/  红枣莲子银耳羹
http://www.haodou.com/recipe/3717/  蜂蜜柚子茶
http://www.haodou.com/recipe/271602/  姜枣桂圆汤
http://www.haodou.com/recipe/273075/  红枣当归粥
http://www.haodou.com/recipe/267272/  米酒南瓜红枣汤

上面几个样例是在我安卓大作业中使用的内容,从种子链接中选择所有的链接通过筛选得到我们所需要的:

public static boolean retrieveLink(org.jsoup.nodes.Element link) {String url = "http://www.haodou.com/recipe/";if (link.attr("abs:href").contains(url)&& !link.attr("abs:href").contains("#")&& !link.attr("abs:href").contains("album")&& !link.attr("abs:href").contains("knowledge")&& !link.attr("abs:href").contains("all")&& !link.attr("abs:href").contains("create")&& !link.attr("abs:href").contains("food")&& !link.attr("abs:href").contains("category")&& !link.attr("abs:href").contains("top")&& !link.attr("abs:href").contains("expert"))return true;return false;}

在每一条子链接中的内容是我们所需要的,所以对应子链接我们需要定义不同的模式来抓取:

public static void getAll(String url) {try {// 样例链接url = "http://www.haodou.com/recipe/869836/";url = "http://www.haodou.com/recipe/326177/";org.jsoup.nodes.Document doc = Jsoup.connect(url).get();
//            成品图Elements elements = doc.select(".recipe_cover");for (Element element : elements)System.out.println(element.attr("abs:src"));
//            步骤图elements = doc.select(".imit_m > img");for (Element element : elements)System.out.println(element.attr("abs:src"));
//            小贴士elements = doc.select(".data");for (Element element : elements)System.out.println(element.text());System.out.println("aaaa");
//            做菜步骤Element prompt = doc.select(".prompt span").first();System.out.println(prompt.text());
//            获取菜名Element title = doc.select("h1").first();
//            result.append(link.text());System.out.println(title.text());
//            菜的简介title = doc.select("[data]").first();
//            result.append(link.text());System.out.println(title.text());
//            食材Elements links = doc.select(".ingtbur");for (Element element : links)
//                result.append(element.text());System.out.println(element.text());//            步骤links = doc.select(".sstep");for (Element element : links)
//                result.append(element.text());System.out.println(element.text());
//            标签links = doc.select("p > a[href]");int i = 0;for (Element element : links) {i++;if (element.attr("abs:href").contains("http://www.haodou.com/recipe/all")) {System.out.println(element.toString());}}elements = doc.select(".quantity");for (Element element : elements)System.out.println(element.text());elements = doc.select(".pop_tags a");for (Element element : elements)System.out.println(element.text());Element element = doc.select(".des span").last();System.out.println(element.text());} catch (IOException e) {e.printStackTrace();}}

得到的结果:

869836,炸茄盒炸茄盒外焦里嫩,入口不腻,咬上一口,淡淡的肉香和茄子的清香同时浮现,让人心动不已。鸡蛋1个姜适量蒜子适量葱适量盐适量白糖适量料酒适量酱油适量老抽适量胡椒粉适量麻油适量面粉适量生粉适量1.首先我们将猪肉剁成肉泥、姜切成姜米、葱切葱花、蒜子切成蒜末、茄子去皮,然后在每一小段中间切一刀,但不要切断,做成茄盒。2.然后我们来制作肉馅:将猪肉泥放入盘中,加入姜米、蒜末、葱花、少许盐、少许白糖、适量料酒、少量酱油、少量老抽、少许胡椒粉、淋入食用油、麻油,抓匀,接着再加入生粉,抓打至肉馅变得粘稠。3.将茄夹中间抹上生粉,用肉馅填满茄夹。4.填满肉馅后,再逐一将整个茄盒抹上生粉。5.接着我们来调面糊:准备一个碗,在碗中放入适量面粉、适量生粉、半勺盐、一个鸡蛋拌匀,再加少许清水,拌至粘稠状,备用。6.锅中放入半锅油,烧至8成热后,将茄盒放入面糊中裹上面糊,再逐个下油锅中,炸至茄盒表面呈金黄色后捞出沥油。这道菜就完成了。菜谱大全健脾开胃儿童减肥宴请家常菜小吃炸白领私房菜聚会

这只是一个样例,我一共抓取了6000+道菜,包括图片和链接资源。


当然如果你想要网页上的其他内容还有很多可以选择:
我建议是最好先抓取所有的内容,然后根据html来选择你要的部分

File input = new File("/tmp/input.html");
Document doc = Jsoup.parse(input, "UTF-8", "http://example.com/");Elements links = doc.select("a[href]"); //带有href属性的a元素
Elements pngs = doc.select("img[src$=.png]");//扩展名为.png的图片Element masthead = doc.select("div.masthead").first();//class等于masthead的div标签Elements resultLinks = doc.select("h3.r > a"); //在h3元素之后的a元素

说明(这个姿势一部分,更加详细的请点击参考文献链接)

jsoup elements对象支持类似于CSS (或jquery)的选择器语法,来实现非常强大和灵活的查找功能。.这个select 方法在Document, Element,或Elements对象中都可以使用。且是上下文相关的,因此可实现指定元素的过滤,或者链式选择访问。Select方法将返回一个Elements集合,并提供一组方法来抽取和处理结果。Selector选择器概述
tagname: 通过标签查找元素,比如:a
ns|tag: 通过标签在命名空间查找元素,比如:可以用 fb|name 语法来查找 <fb:name> 元素
#id: 通过ID查找元素,比如:#logo
.class: 通过class名称查找元素,比如:.masthead
[attribute]: 利用属性查找元素,比如:[href]
[^attr]: 利用属性名前缀来查找元素,比如:可以用[^data-] 来查找带有HTML5 Dataset属性的元素
[attr=value]: 利用属性值来查找元素,比如:[width=500]
[attr^=value], [attr$=value], [attr*=value]: 利用匹配属性值开头、结尾或包含属性值来查找元素,比如:[href*=/path/]
[attr~=regex]: 利用属性值匹配正则表达式来查找元素,比如: img[src~=(?i)\.(png|jpe?g)]
*: 这个符号将匹配所有元素

以下是参考文献:
使用选择器语法来查找元素
Jsoup Cookbook(中文版)
Jsoup实现网络爬虫的整理集合-CSDN
java爬虫中jsoup的使用
java简单爬虫中正则表达式的使用

基于Jsoup实现的简单网络爬虫相关推荐

  1. JAVA——基于HttpComponents(HttpClient)的简单网络爬虫DEMO

    基本概念 HttpComponents(HttpClient): 超文本传输​​协议(HTTP)可能是当今Internet上使用的最重要的协议.Web服务,支持网络的设备和网络计算的增长继续将HTTP ...

  2. python爬虫简单实例-Python 利用Python编写简单网络爬虫实例3

    利用Python编写简单网络爬虫实例3 by:授客 QQ:1033553122 实验环境 python版本:3.3.5(2.7下报错 实验目的 获取目标网站"http://bbs.51tes ...

  3. python新闻聚合_基于Python的新闻聚合系统网络爬虫研究

    基于 Python 的新闻聚合系统网络爬虫研究 左卫刚 [摘 要] 摘 要 本研究旨在创建一个能够从不同页面布局中提取数据的开源爬 虫,其中包括网络爬虫. API .网络爬虫调度器以及 Socket ...

  4. 用python爬虫下载视频_使用Python编写简单网络爬虫抓取视频下载资源

    我第一次接触爬虫这东西是在今年的5月份,当时写了一个博客搜索引擎,所用到的爬虫也挺智能的,起码比电影来了这个站用到的爬虫水平高多了! 回到用Python写爬虫的话题. Python一直是我主要使用的脚 ...

  5. php爬虫邮箱邮件,简单网络爬虫实现爬取网页邮箱

    网络爬虫(又被称为网页蜘蛛,网络机器人,在 FOAF 社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动的抓取 万维网 信息的程序或者 脚本 . 今天我们就以JAVA抓取网站一个页面上的全 ...

  6. python简单网络爬虫_【Python】 简单网络爬虫实现

    介绍网络爬虫(英语:网络爬虫),也称为网络蜘蛛(蜘蛛)是一个Web机器人用于自动浏览万维网.其目的通常是为了编译web索引.\u2014\u2014维基百科web爬虫程序可以节省他们访问的页面,以便搜 ...

  7. 基于Python实现的新闻网络爬虫程序(附完整代码)

    1.2 概要 本文档针对以下三个方面进行了详细说明: 架构说明,对新闻网络爬虫的核心架构进行描述,供开发人员在开发或升级应用时参考 部署说明,对新闻网络爬虫的部署步骤进行描述,供部署人员进行应用部署或 ...

  8. 基于HTTP的简单网络爬虫

    HTTP概述 HTTP是目前使用最广泛的Web应用程序使用的基础协议,例如,浏览器访问网站,手机App访问后台服务器,都是通过HTTP协议实现的. HTTP是HyperText Transfer Pr ...

  9. 使用Python编写简单网络爬虫抓取视频下载资源

    我第一次接触爬虫这东西是在今年的5月份,当时写了一个博客搜索引擎.所用到的爬虫也挺智能的,起码比电影来了这个站用到的爬虫水平高多了! 回到用Python写爬虫的话题. Python一直是我主要使用的脚 ...

最新文章

  1. Python标准库——collections模块的Counter类
  2. 2019年度CSDN博客之星TOP10榜单揭晓,你上榜了吗?
  3. GitHub Draft Pull请求支持新的协作流程
  4. html 标签开发,前端开发入门之HTML基础标签一
  5. 函数动态传参详细,作用域和名称空间,global和nonlocal
  6. HarmonyOS之AI能力·词性标注
  7. Linux运维工程师面试-部分题库
  8. 【Python爬虫练手】lhscan扫图一键下载,搬运辉夜生肉以及制熟肉可用
  9. ESP32 LVGL8.1 ——Roller 滚动 (Roller 24)
  10. CSS+DIV实现圆角
  11. Ubuntu 18.04配置ORB-SLAM2+ROS实时运行ORB-SLAM2+SLAM相关库的安装 相关问题汇总(USB_CAM , ROS 编译问题)
  12. Java并发编程73道面试题及答案 —— 面试稳了 侵立删
  13. java 无法打印_自动打印在Java中不起作用
  14. ubuntu下git搭建服务器(gitosis)
  15. 关于ruoyi验证码无法显示的问题
  16. 主流的音视频SDK调研
  17. C语言编程>第一周 ③ 输入某年某月某日,判断这一天是这一年的第几天
  18. 【mysql】事务的四大特性
  19. 王慧文广发英雄帖:组队拥抱新时代 打造中国OpenAI
  20. 从OKR案例中学到的9个重要的经验教训

热门文章

  1. 俄语翻译专业好就业吗?文件资料俄语翻译多少钱
  2. bond4 交换机配置_网卡bonding模式 - bond0、1、4配置
  3. 带时效性的条形码_具有时效性的二维条形码产生装置的制作方法
  4. 男人最帅的42个瞬间
  5. ppt2010不支持html,ppt2010演示文稿不能使用怎么解决
  6. 【Github系列】学习一下:黑白旧照片上色
  7. asp.net MVC之AuthorizeAttribute浅析
  8. (实况野球)恶灵学院(ダンジョン高校)二周目攻略
  9. listbox 表头自动换行_WPF让ListView或ListBox中的WrapPanel 自动换行
  10. 分享-监控服务器的各种方法