Jsoup简介
主要功能
1. 从一个URL,文件或字符串中解析HTML
2. 使用DOM或CSS选择器来查找、取出数据使用DOM或CSS选择器来查找、取出数据
3. 可操作HTML元素、属性、文本可操作HTML元素、属性、文本
Document dom = Jsoup.connect("www.xxxx.com")..get();
Document对象方法
import org.jsoup.nodes.Document
- Element document.body()
- Element document.head()
- String document.title()
- Elements element.children()
- Element document.getElementById(“id”)
- Elements document.getElementsByAttributeValue(“key”, “value”)
- Elements document.getElementsByClass(“class”)
- Elements document.getElementsByTag(“tag”);
Element对象方法
import org.jsoup.nodes.Element
- String element.attr(“attributeKey”)
- String element.text()
- Elements element.children()
- Element element.getElementById(“id”)
- Elements element.getElementsByAttributeValue(“key”, “value”)
- Elements element.getElementsByClass(“class”)
- Elements element.getElementsByTag(“tag”)
要爬取的数据
分析
-
排名 —一个一位或者两位数 \d{1,2}
-
书名、作者和描述 .*? 匹配所有字符且为非贪婪模式
.
表示匹配除换行符 \n 之外的任何单字符,*
表示零次或多次
-
推荐值 —一个一位小数的百分数 (\d{2}.\d%)
注意,java中要用双斜杠 转义
要匹配的字符串:()为捕获组,即需要爬取的内容
String pattern = "<p class=\"wr_bookList_item_index\">(\\d{1,2})</p>"
+".*?<p class=\"wr_bookList_item_title\">(.*?)</p>"
+".*?<p class=\"wr_bookList_item_author\"><.*?>(.*?)</a>"
+".*?<span class=\"wr_bookList_item_reading_percent\">(\\d{2}.\\d%)"
+".*?<p class=\"wr_bookList_item_desc\">(.*?)</p>";
Re库
// pattern 对象是一个正则表达式的编译表示
Pattern r = Pattern.compile(pattern,Pattern.DOTALL); //DOTALL 表示包括匹配 换行
//Matcher 对象是对输入字符串进行解释和匹配操作的引擎
Matcher m = r.matcher(content.toString());
Matcher 类的方法
索引方法
索引方法提供了有用的索引值,精确表明输入字符串中在哪能找到匹配:
序号 | 方法及说明 |
---|---|
1 | public int start() 返回以前匹配的初始索引。 |
2 | public int start(int group) 返回在以前的匹配操作期间,由给定组所捕获的子序列的初始索引 |
3 | public int end() 返回最后匹配字符之后的偏移量。 |
4 | public int end(int group) 返回在以前的匹配操作期间,由给定组所捕获子序列的最后字符之后的偏移量。 |
查找方法
查找方法用来检查输入字符串并返回一个布尔值,表示是否找到该模式:
序号 | 方法及说明 |
---|---|
1 | public boolean lookingAt() 尝试将从区域开头开始的输入序列与该模式匹配。 |
2 | public boolean find() 尝试查找与该模式匹配的输入序列的下一个子序列。 |
3 | public boolean find(int start**)** 重置此匹配器,然后尝试查找匹配该模式、从指定索引开始的输入序列的下一个子序列。 |
4 | public boolean matches() 尝试将整个区域与模式匹配。 |
替换方法
替换方法是替换输入字符串里文本的方法:
序号 | 方法及说明 |
---|---|
1 | public Matcher appendReplacement(StringBuffer sb, String replacement) 实现非终端添加和替换步骤。 |
2 | public StringBuffer appendTail(StringBuffer sb) 实现终端添加和替换步骤。 |
3 | public String replaceAll(String replacement) 替换模式与给定替换字符串相匹配的输入序列的每个子序列。 |
4 | public String replaceFirst(String replacement) 替换模式与给定替换字符串匹配的输入序列的第一个子序列。 |
5 | public static String quoteReplacement(String s) 返回指定字符串的字面替换字符串。这个方法返回一个字符串,就像传递给Matcher类的appendReplacement 方法一个字面字符串一样工作。 |
通过matcher的捕获组方法可以获得括号内的方法
- m.group(0) pattern的所有内容
- m.group(index)指定下标的捕获组内容
- m.group(1)即对应排名,其他同理
完整代码
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
try {
//Document 对象
//每个载入浏览器的 HTML 文档都会成为 Document 对象
Document dom = Jsoup.connect("https://weread.qq.com/web/category/all").get();
Element content = dom.body(); //网页的内容
// System.out.println(content);
String pattern = "<p class=\"wr_bookList_item_index\">(\\d+)</p>"
+".*?<p class=\"wr_bookList_item_title\">(.*?)</p>"
+".*?<p class=\"wr_bookList_item_author\"><.*?>(.*?)</a>"
+".*?<span class=\"wr_bookList_item_reading_percent\">(\\d{2}.\\d%)"
+".*?<p class=\"wr_bookList_item_desc\">(.*?)</p>";
// pattern 对象是一个正则表达式的编译表示
Pattern r = Pattern.compile(pattern,Pattern.DOTALL); //DOTALL 表示包括匹配 换行
//Matcher 对象是对输入字符串进行解释和匹配操作的引擎
Matcher m = r.matcher(content.toString());
//m.find()返回的是个boolean类型
// 匹配到多个
while(m.find()) {
// group(0)代表匹配pattern全部内容
System.out.println("------------------------------------------------------------------------------");
System.out.println("排名: "+m.group(1)+"\n书名: "+m.group(2)+"\n作者: "+m.group(3)+"\n推荐值: "+m.group(4)+"\n描述: "+m.group(5));
System.out.println("------------------------------------------------------------------------------");
}
}
// 出现错误
catch (IOException e) {
e.printStackTrace();
System.out.println("连接失败");
}
}
}