以爬取Stack Overflow的搜索结果为例,使用Jsoup库编写Java网络爬虫
Jsoup是一个非常好用并且开源的Java爬虫(用来发送请求和解析Html的库),本篇笔记将会介绍如何使用Jsoup编写一个简单的网络爬虫,用来获取Stack Overflow的搜索结果
Jsoup官网有非常棒的文档,建议有能力的可以直接参考;
下面开始编写一个自己的Demo
首先创建一个Maven工程项目,并在
pom.xml
文件中导入jsoup包引用1
2
3
4
5<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.11.2</version>
</dependency>
创建一个java文件,命名为
JsoupTest.java
引入需要的相应的引用1
2
3
4
5import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
进入Stack Overflow首页,以IOException为例搜索一下,然后打开调试工具查看网页的结构,我们需要获取每个问题、问题的摘要以及问题的链接。
选取我们需要的结果区域,可以看到我们要的元素在一个类型为
question-summary
的div
下一个类型为summary
的div
下,其中:class="result-link"
里面存着问题以及问题的链接;class="excerpt"
里面存着问题的摘要;class="tags"
里面存着问题的标签;class="started"
里面存着提问日期
知道结构以后就可以开始编写爬虫了
首先定义URL,Stackoverflow使用GET请求的方式来进行搜索,所以创建两个串
1
2static String url = "https://stackoverflow.com/search?q=";
static String query = "IOException";第二个query串就是要搜索的内容,前面是查询url的前缀
然后使用Jsoup发送请求,把query直接接在url后面就行
1
Document doc = Jsoup.connect(url+query).get();
doc为收到的response,也就是整个页面,这时候就可以使用Jsoup的解析功能来提取我们需要的内容了:
提取
question-summary
类下的summary
类(CSS语法)1
Elements elements = doc.select(".question-summary .summary");
这样将得到一个Html元素的队列,然后迭代地进行内容的提取
1
2
3
4
5
6
7for(Element e : elements){
Elements title = e.select(".result-link h3 a");
System.out.println("title: " + title.get(0).attr("title"));
System.out.println("url: " + title.get(0).absUrl("href"));
Elements excerpt = e.select(".excerpt");
System.out.println("Excerpt: " + excerpt.text() + "\n");
}同样也是采用CSS语法,attr()方法会获取元素里的某个属性值(Attribute),由于很多页面内的链接都是相对路径,absurl()会获取href属性中的url后,自动形成我们需要的绝对路径,text()将会获取元素中的文本元素(不包含标签),html()则是获得该元素下的所有内容;
然后查看显示结果
1
2
3
4
5
6
7
8
9
10
11
12title: HttpClient request throws IOException
url: https://stackoverflow.com/questions/13141434/httpclient-request-throws-ioexception
Excerpt: The following code throws a IOException with the message: "The specified registry key does not exist." HttpClient client = new HttpClient(); Uri uri = new Uri("http://www.google.com …
title: How to avoid Java code in JSP files?
url: https://stackoverflow.com/questions/3177733/how-to-avoid-java-code-in-jsp-files/3180202#3180202
Excerpt: , IOException { if (((HttpServletRequest) request).getSession().getAttribute("user") == null) { ((HttpServletResponse) response).sendRedirect("login"); // Not logged in, redirect to login page … ServletException, IOException { try { List<Product> products = productService.list(); // Obtain all products. request.setAttribute("products", products); // Store products in …
title: Understanding Java IOException
url: https://stackoverflow.com/questions/5819121/understanding-java-ioexception
Excerpt: I need some help with understanding the IOException. I've reviewed a lot of information on the internet, and looked at the technical specifications at Oracle's Java website. Am I correct in my … understanding of the IOException class and all of it's sub-classes, that there are no associated "error messages" or "return code" values? So if one wanted to issue some message and/or return code value …
...
完成我们要的提取