最近在项目中做一个需求,将一个网页中的外部的图片下载到我们自己的服务器,方法就是对html里的内容匹配出img标签的src的地址,然后利用这个地址下载图片,但总是会出现有的src的地址不是正确的图片资源,出现下载错误的情况,而我在img标签中发现还有data-src属性或者original-src属性,且这些属性里的地址是可下载的。
这就为我带来一个思路,匹配出img标签中所有属性中包含src字符串的都筛选出来。如果src的地址下载不了,那就用data-src或者其他的带src字符串属性的地址去下载。
关于怎么获取img标签中的src的属性,大家可能都了解用正则表达式去匹配。
这里先用正则表达式做个小测试吧:
输出结果:
img标签-------------<img width="200" data-src="/image/261/1.jpeg" alt=""/>src属性-------------/image/261/1.jpegimg标签-------------<img width="200" src="/image/751/3.jpg" alt=""/>src属性-------------/image/751/3.jpgimg标签-------------<img width="200" src="/image/132/5.jpeg" alt=""/>src属性-------------/image/132/5.jpeg今天刚接触用jsoup去解析html标签,发现非常方便,比用自己辛辛苦苦去写正则方便多了,正则整个写完,过一段时间再来看这个正则表达式,估计就看不懂了。
下面就介绍用jsoup解析网页:
我截取下面这个网址的部分源代码
http://domestic.firefox.sina.com/17/0412/08/4OPJ52GTXH0M3V9W.html
部分源代码
我们不再用正则表达式去获取这里a标签里的href属性以及img标签里的src属性,而是用jsoup的方法去解析。
到网上下载jsoup的jar包,我分享到百度云盘了:http://pan.baidu.com/s/1jIE7fBS,将jar包添加到我们的项目中。
import org.jsoup.Jsoup;import org.jsoup.nodes.Document;import org.jsoup.nodes.Element;import org.jsoup.select.Elements;public class TestJsoup { public static void main(String[] args) throws Exception { Document doc = Jsoup.connect("http://domestic.firefox.sina.com/17/0412/08/4OPJ52GTXH0M3V9W.html").get(); //获取 带有src属性的img元素 Elements imgTags = doc.select("img[src]"); System.out.println("=====imgsTag===="+imgTags); for(Element element:imgTags){ String src=element.attr("abs:src");//获取src的绝对路径 String src2=element.attr("src");//获取src的绝对路径 System.out.println("===src==="+src); System.out.println("===src2==="+src2); } //获取 带有href属性的a元素 Elements aTag = doc.select("a[href]"); System.out.println("=====aTag===="+aTag); for(Element element :aTag){ String href=element.attr("href"); System.out.println("===href==="+href); } //所有引用jpg图片的元素 Elements jpgs = doc.select("img[src$=.jpg]"); for(Element element :jpgs){ String src=element.attr("abs:src"); System.out.println("===src==="+src); } }}代码中
String src=element.attr("abs:src"); String src2=element.attr("src");区别就是前者可以获取到src地址的绝对路径。
Element的attr方法,获取的是属性名为“src”的值,如果我们要像上面的正则表达式一样,将属性名中包含字符串”src”的属性也获取到,但是我们不知道这个包含“src”字符串的属性到底是什么,可能是data-src,也可能是original-src,甚至是其他的,这种情况我们只能变历img标签中的所有属性了。
比如像下面的这种情况,我们获取data-src的属性。
<p><img data-src="http://mmbiz.qpic.cn/mmbiz_jpg/LoyT0npAgkkRjJibID5PXg2zT6iarg9IMkdqpvGv58Fq9tSGUGibZibX2uYfibIryXPuwX44SRjGrY4JURnAvPqvaOQ/0?wx_fmt=jpeg" data-ratio="0.66625" data-w="800" src="http://mmbiz.qpic.cn/mmbiz_jpg/LoyT0npAgkkRjJibID5PXg2zT6iarg9IMkdqpvGv58Fq9tSGUGibZibX2uYfibIryXPuwX44SRjGrY4JURnAvPqvaOQ/640?wx_fmt=jpeg&tp=webp&wxfrom=5&wx_lazy=1" data-fail="0" alt="" /></p>可以遍历img标签的属性:
Document doc = Jsoup.connect("http://domestic.firefox.sina.com/17/0412/08/4OPJ52GTXH0M3V9W.html").get(); //获取 带有src属性的img元素 Elements imgTags = doc.select("img[src]"); for(Element element:imgTags){ Attributes node=element.attributes(); Iterator<Attribute> iterator=node.iterator(); while (iterator.hasNext()) { Attribute attribute=iterator.next(); String key=attribute.getKey(); //属性中包含“src”字符串,但不是src的属性 if (!key.equals("src")&&key.indexOf("src")!=-1) { //element.removeAttr(key); String otherSrc=attribute.getValue(); System.out.println("====otherSrc===="+otherSrc); break; } } }