Jsoup是一款Java 的HTML解析器,可直接解析某個URL地址芜飘、HTML文本內(nèi)容务豺。它提供了一套非常省力的API,可通過DOM嗦明,CSS以及類似于jQuery的操作方法來取出和操作數(shù)據(jù)笼沥。
爬取過程
1 網(wǎng)頁是基于get請求獲取到的,無需攜帶參數(shù)請求資源
Step1: 基于get請求獲取Url對于網(wǎng)頁的HTML
Connection con = Jsoup.connect(目標(biāo)網(wǎng)頁Url);
Step2:利用Jsoup把Html解析為Document
//這里有時候get()會報錯娶牌,try... catch 解決
Document document = con.get();
Step3:利用Dom方法獲取標(biāo)題奔浅、發(fā)布時間、內(nèi)容等
//獲取所有元素中第一個class= "list” 的元素
Element element = document.getElementsByClass("list").first()
//獲取 class= "list” 的元素中所有l(wèi)i元素诗良,放在elements對象里
Elements elements = element.getElementsByTag("li")
//遍歷取出elements中所有<a>標(biāo)簽中包含的連接
for(Element ele:elements){
//contentUrl為<a>標(biāo)簽href屬性中某網(wǎng)站Url后半部分鏈接
String contentUrl = ele.getElementsByTag("a").attr("href");
//拼接出完整的detailUrl
String detailUrl = "某網(wǎng)站Url前半部分" + contentUrl;
//基于get請求獲取detailDocument中Html
Document detailDocument = Jsoup.connect(detailUrl).get();
//利用Dom方法獲取詳細(xì)頁面里的標(biāo)題汹桦、日期、內(nèi)容等鉴裹。
String title = detailDocument.getElementsByClass("detail_bigtitle").first().text();
System.out.println("標(biāo)題:"+ title);
String time = detailDocument.getElementsByClass("time").first().text();
//這里導(dǎo)入java實例 SimpleDateFormat舞骆,格式化時間
SimpleDateFormat srtFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = srtFormat.parse(time);
System.out.println("日期:"+ date);
String content= detailDocument.getElementsByClass("detail_txt").first().getElementsByTag("p").text();
System.out.println("內(nèi)容:"+ content);
//從標(biāo)題判斷所屬類型
//利用余弦相似度計算
String caseType = Cosine.getSimilarityList(title);
System.out.println("案件類型:"+ caseType);
System.out.println("——————————————————————");
}
2 網(wǎng)頁是基于POST請求,需要攜帶參數(shù)請求資源
利用POST請求径荔,攜帶請求參數(shù)督禽,從接口處獲取資源
Connection connect = Jsoup.connect("上圖中requestURL");
// 利用headers
connect.header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3");
connect.header("Cookie", "值");
connect.header("Referer", "值");
connect.header("Host", "值");
connect.header("User-Agent", "值");
connect.header("Upgrade-Insecure-Requests", "1");
//利用form data
connect.data("searchField", "值");
connect.data("keywords", "值");
//這個pageIndexNow是自動翻頁的值,可以不寫死,實現(xiàn)爬取的自動翻頁
connect.data("pageIndexNow", "值");
connect.data("pageSizeNow", "值");
connect.data("currentSubid", "值");
connect.data("Type", "值");
//發(fā)送帶參數(shù)的post請求
Document document = connect.post();
System.out.println(document.toString());
上面的代碼為通過POST請求方式,document為獲取到的HTML手趣,接下來通過操作Dom獲取到需要的標(biāo)題临燃、日期、內(nèi)容等。在取<a>標(biāo)簽屬性的過程中,可以加入判斷,看是否能取到<a>鏈接中href屬性第岖,若不為空拼接字符串
for (Element ele : elements) {
//取時間
if (!"案例報送時間".equals(ele.getElementsByTag("td").get(1).text())){
date = ele.getElementsByTag("td").get(1).text();
}
String contentUrl = ele.getElementsByTag("a").attr("href");
//判斷能否取到tr中的a鏈接,若不為空則拼接字符串
if (!"".equals(contentUrl) && contentUrl != null) {
detailUrl = "某網(wǎng)站Url前半部分" + contentUrl;
//遍歷存在list里的第一頁的所有案件詳情鏈接试溯,調(diào)用detailData函數(shù)
detailData(detailUrl, date);
}
}
detailData函數(shù):傳遞參數(shù)(String detailUrl, String date)到函數(shù)中蔑滓,訪問通過拼接Url獲取到的每一個detailUrl鏈接中的內(nèi)容
public Boolean detailData (String detailUrl, String date) {
//格式化日期
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Date judgeDate = null;
try {
judgeDate = formatter.parse(date);
} catch (ParseException e) {
e.printStackTrace();
}
//訪問每一個拼接好的頁面 需要用到帶參數(shù)的POST請求,具體什么請求看 F13 NetWork里的.
Connection connectPOST = Jsoup.connect(detailUrl);
//從拿到的detailUrl截取字符串
String dbid = detailUrl.substring(36,38);
String dbname = detailUrl.substring(46,50);
String sysid = detailUrl.substring(detailUrl.lastIndexOf("=")+1) ;
String id = dbid + sysid;
//利用headers
connectPOST.header("Accept", "值");
connectPOST.header("Cookie", "值");
connectPOST.header("Referer", "值");
connectPOST.header("Origin", "值");
connectPOST.header("User-Agent", "值");
connectPOST.header("Content-Type", "值");
//利用data
connectPOST.data("dbID", "");
connectPOST.data("dbName", "");
connectPOST.data("sysID", "");
//帶參數(shù)結(jié)束
Document pageDocument = null;
try {
pageDocument = connectPOST.post();
} catch (IOException e) {
e.printStackTrace();
}
//取標(biāo)簽
Element divElement = pageDocument.getElementsByClass("wzinfo").first();
//標(biāo)題
System.out.println("id:"+ id);//拼接字符串
//日期
System.out.println("日期:"+ judgeDate);
String title = divElement.getElementsByTag("h3").text();
System.out.println("標(biāo)題:"+ title);
//詳情
List<String> contentList = new ArrayList<>();
String content = null;
Elements conElement = divElement.getElementsByClass("contentspan").tagName("p");
for (Element ele : conElement){
content = ele.getElementsByTag("p").text();
contentList.add(content);
}
System.out.println("詳情:"+ contentList);
System.out.println("-------------------------------------------------------------------");
return true;
}
解釋這里為什么需要從拼接好的截取detailUrl中截取字符串呢遇绞?是因為在發(fā)送POST請求的過程中键袱,動態(tài)獲取detailUrl中的字符串作為請求參數(shù),如下圖:
POST請求的
某網(wǎng)站從DetailUrl中動態(tài)獲取