前言
当一个项目完成的时候,我们需要进行测试,但是测试的时候测试的数据怎么来呢?比如类似于携程酒店搜索的页面,怎么去找一些酒店的简单信息和描述信息呢?我们可以通过瞎编,这样其实最简单,没有什么要求,我们还可以通过写一些脚本去这些现成的网站上去抓取一些数据下来,岂不美哉?
思路
通过Java中的HTML相关操作类通过一些网页上源代码中的共同点将我们需要的数据抓取下,进行展示。
开发环境
- Java1.8.0
- Maven 3.5
- Tomcat 7.0
基本知识
- URL类
java.net.URL创建一个URL对象
URL urlObj = new URL(String url); //通过一个绝对资源的绝对地址,创建一个URL的对象指向这个资源
- URLConnection类
java.net.URLConnection通过一个URL对象创建一个request请求
URLConnection urlConnection = urlObj.openConnection();
- IO流
主要使用InputStreamReader和BufferedReader这两个类 - Jsoup类
将一个HTML文件转换成一个Document对象 - Document类
相当于js中的document对象 - Elements类
HTML中element的集合 - Element类
HTML中的节点对象
核心方法
- 通过一个网页的URL和对应的编码获取到改网页的源代码
public static String getHtmlResourceByUrl(String url, String encoding) {
//return urlResource
StringBuilder urlResource = new StringBuilder();
//io
InputStreamReader inReader = null;
try {
//create connection
URL urlObj = new URL(url);
//open connection
URLConnection urlConnection = urlObj.openConnection();
//get resource inputstreamReader
inReader = new InputStreamReader(urlConnection.getInputStream(), encoding);
//create cache
BufferedReader bufferReader = new BufferedReader(inReader);
//line of resource
String line = "";
while(null != (line=bufferReader.readLine())) {
urlResource.append(line).append("\n");
}
} catch (Exception e) {
e.printStackTrace();
}finally {
if(null != inReader) {
try {
inReader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
return urlResource.toString();
}
- 通过一个网页的URL和对应的编码筛选到需要的信息
public static List<Map<String, String>> getHtmlDataByUrl(String url, String encoding) {
List<Map<String, String>> hotelMapList = new ArrayList<Map<String, String>>();
//get htmlResource
String htmlResource = getHtmlResourceByUrl(url, encoding);
//analysis htmlResource
Document document = Jsoup.parse(htmlResource);
//get hotel list
Elements hotelList = document.getElementsByClass("searchresult_list");
//get hotel message, put it to a map and add to hotelMapList
for(Element hotel : hotelList) {
Map<String, String> hotelMap = new HashMap<String, String>();
String hotelImgUrl = hotel.getElementsByTag("img").attr("src");
String hotelTitle = hotel.getElementsByTag("img").attr("alt");
String hotelDescribe = hotel.getElementsByClass("searchresult_htladdress").text();
hotelMap.put("hotelImgUrl", hotelImgUrl);
hotelMap.put("hotelTitle", hotelTitle);
hotelMap.put("hotelDescribe", hotelDescribe);
hotelMapList.add(hotelMap);
}
return hotelMapList;
}
总结
两个方法都很简单,第一个方法应该没有什么问题,但是第二个方法局限性太强,这次是针对于携程酒店查询的页面数据,但是如果我想去抓取美团酒店页面的数据就不能成功了,因为每一个页面的布局都是不同的,这种抓取的方式只能针对一种页面,如果页面改变了,就需要按照改变后的页面布局去改变代码才能完成抓取。