使用Jsoup解析网页
来源:互联网 发布:微信朋友圈网络出错 编辑:程序博客网 时间:2024/05/16 14:10
之前已经发表过一篇使用HtmlParser类来解析视频网站的教程
http://blog.csdn.net/gfd54gd5f46/article/details/54960538
我发现htmlparser类太旧了,而且用起来语法也不清晰。
所以我又找来一个更强大的解析网页的工具类:Jsoup 来帮助我们制作更强大的网络爬虫
下载Jsoup类
jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。
Jar包地址:
http://jsoup.org/packages/jsoup-1.8.1.jar
构建Maven项目自动下载jar包:
http://blog.csdn.net/gfd54gd5f46/article/details/54973954
Jsoup在线API文档:
http://tool.oschina.net/apidocs/apidoc?api=jsoup-1.6.3
Jsoup开发指南:
http://www.open-open.com/jsoup/attributes-text-html.htm
解析网页
我这里就找一个图片网站来进行测试
http://www.nipic.com/index.html
1、获取单张图片的下载地址
- 随便点击一张首页的图片
进去之后我们发现这个页面只是图片的列表,我们要获取的是单个图片的地址,所以还需要点击进去查找
点击第一张图片,查看到了单张图片
同样,我们要对这个页面进行分析,找到规律来获取这张图片的地址链接
F12进入调试页面
(调试页地址:http://www.nipic.com/show/16519633.html)
观察规律发现:
图片的下载地址在src属性下
图片有个唯一的id属性:J_worksImg
找到规律后,我们就来使用Jsoup来获取一下图片的下载地址
- 代码实现:
/** * 通过子页面链接(图片网页)获取到图片下载地址 * "http://www.nipic.com/show/16519633.html" * @return downloadPicUrl */ public static List<String> getPicDownUrlFromAllPicPage(String url) { //保存图片的下载地址 List<String> list = new ArrayList<String>(); try { //通过传入一个url打开一个链接并且获取内容,将内容存到文件中 Document doc = Jsoup.connect(url).get(); //如果文档不为空 && 页面中没有出现 “唔,未找到任何页面!!!” 则认为该页面是个正常页面 if (doc != null && !Jsoup.connect(url).get().html().contains("唔,未找到任何页面!!!")) { //获取到网页的唯一的id元素 Element element = doc.getElementById("J_worksImg"); //判断元素不为空 && src里面的内容不为空 if (element != null && !element.attr("src").equals("")) { //将图片地址添加到集合中 list.add(element.attr("src")); } } } catch (IOException e) { e.printStackTrace(); } //http://pic120.nipic.com/file/20170114/958400_203916268000_2.jpg return list; }
Main方法()
public static void main(String[] args) { //程序第一个运行的时间(毫秒) long begin = System.currentTimeMillis(); List<String> list = getPicDownUrlFromAllPicPage("http://www.nipic.com/show/16519633.html"); for (String string : list) { System.out.println("图片下载地址:" + string); } //输出程序最后所花费的时间 System.out.println("\n\n用时:" + (System.currentTimeMillis() - begin)/1000f + "s"); }
这样我们就拿到了图片的下载地址了
对下载地址进行切割
我们可以再写一个方法,将每个图片的下载链接进行切割,拿到图片名
/** * 将图片下载地址进行切割,得到文件名 * 根据传入的url地址,获取文件的名称 * @param url * @return name */ public static String getNameFromUrl(String url) { //找到最后一个 "/" 的位置 int beginIndex = url.lastIndexOf("/"); //截取 "/" 后面的内容 String name = url.substring(beginIndex + 1); return name; }将刚刚的图片下载地址放进去System.out.println(getNameFromUrl("http://pic120.nipic.com/file/20170114/958400_203916268000_2.jpg"));
这样就拿到了图片名,方便后续保存工作
2、获取单个列表里面所有的图片介绍页面
既然我们能通过图片介绍页面来获取到图片的下载地址,那我们能不能把整一个图片列表的所有图片介绍页面都获取到呢?
我们分析一下图片列表的网页
http://www.nipic.com/topic/show_27036_1.html?ll
定位到第一张图片发现 这个介绍页面有一个class属性 ,并且有个值:block works-detail hover-none
查找一下这个值发现 有40条数据,而且都是我们所关注的内容
既然知道了规律之后,那我们就来获取一下这个列表下的所有图片介绍页面
- 代码实现:
/** * 获取分页里的所有的子页面地址 * @param OnePage 传入一个图片列表页面 * "http://www.nipic.com/topic/show_27036_1.html" */ public static List<String> getAllPicPageFromOnePage(String OnePage) { List<String> list = new ArrayList<String>(); try { Document doc = Jsoup.connect(OnePage).get(); //获取所有包括该class属性的元素 Elements elements = doc.getElementsByClass("block works-detail hover-none"); System.out.println("当前页面有:" + elements.size() + " 子页面\n"); for (Element element : elements) { //将获取到的元素添加到集合 list.add(element.attr("href")); } } catch (IOException e) { e.printStackTrace(); } return list; }
Main方法
public static void main(String[] args) { //程序第一个运行的时间(毫秒) long begin = System.currentTimeMillis(); List<String> list = getAllPicPageFromOnePage("http://www.nipic.com/topic/show_27036_1.html"); for (String string : list) { System.out.println(string); } //输出程序最后所花费的时间 System.out.println("\n\n用时:" + (System.currentTimeMillis() - begin)/1000f + "s"); }
确实获取到了我们想要的这40个页面
3、获取所有的分页列表页面
既然我们能通过一个列表页面来获取所有的图片介绍页面,那么我们能不能获取到所有的列表页面的呢?
我们继续来分析页面
http://www.nipic.com/topic/show_27036_1.html?ll
从网页源码中可以发现,每个列表页面链接都有一个class属性,并且属性里面都包涵有“ eo-page-num“ 的内容
查找一下整个页面有多少包涵“eo-page-num”内容的数据
- 发现只有3个地方有这个页面(也就是说只有3个列表)
知道规律之后,我们就来获取一下这个页面的所有分页列表
- 代码实现
/** * 获取所有的图片列表页面 * "http://www.nipic.com/topic/show_27036_1.html?ll" */ public static List<String> getAllPicPage(String url) { List<String> list = new ArrayList<String>(); try { Document doc = Jsoup.connect(url).get(); //获取所有包括该class属性的元素 Elements elements = doc.getElementsByClass("seo-page-num"); System.out.println("共有:" + elements.size() + " 个分页"); for (Element element : elements) { //将元素中的href值添加到集合中 list.add(element.attr("href")); System.out.println(element.attr("href")); } } catch (IOException e) { e.printStackTrace(); } return list; }
Main方法()
public static void main(String[] args) { //程序第一个运行的时间(毫秒) long begin = System.currentTimeMillis(); List<String> list = getAllPicPage("http://www.nipic.com/topic/show_27036_1.html"); for (String string : list) { System.out.println(string); } //输出程序最后所花费的时间 System.out.println("\n\n用时:" + (System.currentTimeMillis() - begin)/1000f + "s"); }
确实获取到了所有的列表页面
http://www.nipic.com/topic/show_27036_1.html
http://www.nipic.com/topic/show_27036_2.html
http://www.nipic.com/topic/show_27036_3.html
实战
下载所有列表的图片:
1、 获取所有的列表页面
2、 获取每个列表页面的所有图片介绍页面
3、 通过介绍页面获取下载地址
4、 对下载地址进行切割拿到图片名
5、 通过下载链接跟图片名,将所有的图片下载到images目录
在项目下创建一个images目录用来保存图片
- 代码实现
package com.lingdu.jsoup;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.FileOutputStream;import java.io.IOException;import java.net.MalformedURLException;import java.net.URL;import java.util.ArrayList;import java.util.List;import org.jsoup.Jsoup;import org.jsoup.nodes.Document;import org.jsoup.nodes.Element;import org.jsoup.select.Elements;/** * 下载图片Demo * 2017-2-10 * LingDu */public class GetPicDemo { /** * 5、下载图片 * 到nipic网站下载图片 * 传入图片下载地址即可下载到images目录下 */ public static void downloadPic(String myUrl) { if (!myUrl.equals("")) { try { URL url = new URL(myUrl); BufferedInputStream bis = new BufferedInputStream(url.openConnection().getInputStream()); byte myArray[] = new byte[1024*1024]; int len = 0; String fileName = getNameFromUrl(myUrl); //System.out.println(fileName); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("images/" + fileName)); while((len = bis.read(myArray)) != -1){ bos.write(myArray, 0, len); } bos.flush(); bos.close(); bis.close(); System.out.println("图片:" + fileName +" ------>下载成功!"); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } /** * 4、将图片下载地址进行切割,得到文件名 * 根据传入的url地址,获取文件的名称 * @param url * @return name */ public static String getNameFromUrl(String url) { //找到最后一个 "/" 的位置 int beginIndex = url.lastIndexOf("/"); //截取 "/" 后面的内容 String name = url.substring(beginIndex + 1); return name; } /** * 3、通过子页面链接(图片网页)获取到图片下载地址 * "http://www.nipic.com/show/16519633.html" * @return downloadPicUrl */ public static List<String> getPicDownUrlFromAllPicPage(String url) { //保存图片的下载地址 List<String> list = new ArrayList<String>(); try { //通过传入一个url打开一个链接并且获取内容,将内容存到文件中 Document doc = Jsoup.connect(url).get(); //如果文档不为空 && 页面中没有出现 “唔,未找到任何页面!!!” 则认为该页面是个正常页面 if (doc != null && !Jsoup.connect(url).get().html().contains("唔,未找到任何页面!!!")) { //获取到网页的唯一的id元素 Element element = doc.getElementById("J_worksImg"); //判断元素不为空 && src里面的内容不为空 if (element != null && !element.attr("src").equals("")) { //将图片地址添加到集合中 list.add(element.attr("src")); } } } catch (IOException e) { e.printStackTrace(); } //http://pic120.nipic.com/file/20170114/958400_203916268000_2.jpg return list; } /** * 2、获取分页里的所有的子页面地址 * @param OnePage 传入一个图片列表页面 * "http://www.nipic.com/topic/show_27036_1.html" */ public static List<String> getAllPicPageFromOnePage(String OnePage) { List<String> list = new ArrayList<String>(); try { Document doc = Jsoup.connect(OnePage).get(); //获取所有包括该class属性的元素 Elements elements = doc.getElementsByClass("block works-detail hover-none"); System.out.println("当前页面有:" + elements.size() + " 子页面\n"); for (Element element : elements) { //将获取到的元素添加到集合 list.add(element.attr("href")); } } catch (IOException e) { e.printStackTrace(); } return list; } /** * 1、获取所有的图片列表页面 * "http://www.nipic.com/topic/show_27036_1.html?ll" */ public static List<String> getAllPicPage(String url) { List<String> list = new ArrayList<String>(); try { Document doc = Jsoup.connect(url).get(); //获取所有包括该class属性的元素 Elements elements = doc.getElementsByClass("seo-page-num"); System.out.println("共有:" + elements.size() + " 个分页"); for (Element element : elements) { //http://www.nipic.com/topic/show_27036_1.html //http://www.nipic.com/topic/show_27036_2.html //http://www.nipic.com/topic/show_27036_3.html //将元素中的href值添加到集合中 list.add(element.attr("href")); } } catch (IOException e) { e.printStackTrace(); } return list; } /** * 这个方法处理所有逻辑 */ public static void downloadAll() { //拿到图片列表页面 List<String> picPagelist = new ArrayList<String>(); //拿到所有图片下载页面 List<String> allPicPageList = new ArrayList<String>(); //拿到图片的下载地址 List<String> picDownUrlList = new ArrayList<String>(); picPagelist = getAllPicPage("http://www.nipic.com/topic/show_27036_1.html?ll"); for (String str : picPagelist) { System.out.println("\n页面:----------------->" + str); allPicPageList = getAllPicPageFromOnePage(str); for (String str1 : allPicPageList) { try { picDownUrlList = getPicDownUrlFromAllPicPage(str1); for (String str2 : picDownUrlList) { downloadPic(str2); } } catch (Exception e) { e.printStackTrace(); } } } } public static void main(String[] args) { //程序第一个运行的时间(毫秒) long begin = System.currentTimeMillis(); //调用所有方法的整合体 downloadAll(); //输出程序最后所花费的时间 System.out.println("\n\n用时:" + (System.currentTimeMillis() - begin)/1000f + "s"); }}
这样就下载到了所有的图片了
查看一下images目录 ,确实把所有列表的图片都下载下来了,总共有92张图片
实现原理
分析网页找到规律
依次往下嵌套循环即可获取到下载地址
最终完成下载
- 使用Jsoup解析网页
- Android使用jsoup解析网页
- Android:使用jsoup解析网页
- 使用Jsoup解析html网页
- 使用Jsoup解析html网页
- Java使用Jsoup解析网页
- 使用Jsoup解析html网页
- android中使用JSOUP如何解析网页
- java 使用Jsoup解析URL网页信息
- 网页解析利器Jsoup
- 网页解析利器Jsoup
- Jsoup 解析Html网页
- Jsoup解析网页
- 网页解析之Jsoup
- jsoup解析网页二
- Jsoup解析网页内容
- android中使用JSOUP如何解析网页数据详述
- 使用java开源工具jsoup抓取解析网页数据
- 爬虫项目(二)用phantomjs做爬虫
- 冒泡排序
- 关于List集合转化为数组
- 2.4 VB编程基础--常量
- (二十)文本流与数据流
- 使用Jsoup解析网页
- linux的gdb总结
- 产品研发记录05:产品研发人员应当具备的特质
- Android studio2.2.3 支持Java8
- C与C++文件的相互引用
- Python利用openpyxl库遍历Sheet的方法
- 线程池介绍
- 分布式数据访问层(DAL)
- hbase空间清理