使用jsoup简单抓取html页面内容
我打算抓取一些页面上的数据。
之前了解过有关的一点概念,想法是用正则匹配。
真正实施后发现用正则有点可怕,有点难,在于我可以匹配找到div的头,不好找到该div的尾等等。
再次想,感觉如果可以像jquery一样,通过融入dom中去,然后取出dom中所需要的元素的内容或者属性。想法是使用java删除在页面中的与js有关的东西(页面有些事残缺的,因为js引用或者css引用可能不存在,为了保证js正常能用,所以将其他切除),然后自己增加<script></script>并且在脚本中进行查询,用js打印想要的内容到文件中。这个有点技术难度,因为我不可能自己每次生成网页副本,删除东西,添加东西,再在浏览器运行。这个需要一个智能,所以可能涉及到在java中运行html,js等恶心,暂时放过。
后面朋友给我推荐jsoup,看了下,有点感觉,xml就是html的祖宗,为什么不使用xml的遍历服务等方式找到想要的元素呢?
jsoup就是这种思想,实现了类似jquery的简单效果。
我参考的这里的文档:
http://www.open-open.com/jsoup/
代码:
package test; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import org.junit.Test; import java.io.File; import java.text.SimpleDateFormat; import java.util.Calendar; /** * Created by zhen on 2017-06-02. */ public class ParseHtmlTest { @Test public void run(){ File input = new File("C:\\Users\\zhen\\Desktop\\beFetch.html"); try{ Document doc = Jsoup.parse(input, "UTF-8", ""); // Document doc = Jsoup.connect("https://consumeprod.alipay.com/record/standard.htm").get(); 进不去,登陆支付宝页面!!! Element contents = doc.getElementById("J_home-record-container"); Elements trs = contents.select("table tbody tr.J-item"); for(Element tr : trs){ //时间 Elements timers = tr.select("td.time"); System.out.println("时间:" + parseDataString(timers.select("p").get(0).text()) + " " +timers.select("p").get(1).text()); //对方单位 Elements name = tr.select("td.name"); String title = name.select("p.consume-title").select("a").text(); String opposite = name.select("p.name.p-inline.ft-gray").get(0).text(); String serialNumber = name.select("div a.J-tradeNo-copy.J-tradeNo").get(0).attr("title"); System.out.println("交易类型:" + title + " ,对方单位: " + opposite + ",流水号: " + serialNumber); //交易金额 Elements ammount = tr.select("td.amount"); System.out.println("交易金额:" + ammount.get(0).text()); //交易状态 Elements status = tr.select("td.status"); String statu = status.select("p.text-muted").get(0).text(); System.out.println("交易状态:" + statu); } }catch(Exception ex){ ex.printStackTrace(); } } public String parseDataString(String time){ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); Calendar calendar = Calendar.getInstance(); String today = sdf.format(calendar.getTime()); calendar.set(Calendar.DAY_OF_MONTH , -1); String yesterday = sdf.format(calendar.getTime()); if("今天".equals(time)){ return today; }else if("昨天".equals(time)){ return yesterday; }else{ return time; } } }
这里主要用到了Element对象,Elements对象,Document对象,Node等对象。主要用到了几个方法:
Jsoup.parse
Jsoup.connect
doc.getElementById
element.select
element.text
element.attr
等。具体使用看文档。
抓取效果: