获取小说站点章节列表
第一次写博客,写得不好请见谅
目的是让自己印象更加深刻,锻炼自己表达能力,同时可以和大家一起交流学习,大神勿喷!
本次学习教程来自吾爱破解小说站点爬虫-spring-mybatis-jsoup-http-client
讲师:昕悦阁丶风雪
目录
观察章节列表所用到的元素
章节列表所用到的元素,如a标签、table标签等
打开笔趣阁-圣墟网页,查看所列的章节列表
查看源代码
可以发现每一个章节都使用了dd和a标签,且章节都在id=list下,所以不难理解为每个章节从#list到dd标签再到a标签。
大家可以去各大小说站点观察发现
以下是我所观察的小说站点及对应的章节所使用的元素
顶点小说23wx.com
#at td a
笔下文学bxwx8.org
#TabCss dd a
笔趣阁biquge.tw
#list dd a
创建maven项目及配置
本项目是eclipse创建的
创建maven项目
File–>new–>Maven Project
配置项目
右击项目选择Properties
选择Java Build Path–>Libraries
选中JER System Library 点击Edit
选择自己安装的jdk版本,这里我用的是jdk1.8.0_121
选择Java Compiler设置与jdk相应的Compiler compliance level
3.配置pom.xml文件,下载所需要的jar包
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>luohong</groupId>
<artifactId>novel.spider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- 依赖包 -->
<dependencies>
<!-- HTML解析器工具 -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.9.2</version>
</dependency>
<!-- Http传输协议工具包 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
<!-- 解析xml工具包 -->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<!-- 单元测试工具包 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
</project>
4.项目结构
编写代码
1、编写章节实体类 Chapter.java
package novel.spider.model;
import java.io.Serializable;
/**
* 小说的章节实体
* @author luohong
* @date 2017年2月12日
*/
public class Chapter implements Serializable {
private static final long serialVersionUID = 1L;
private String title; // 标题名
private String url; // 链接
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((title == null) ? 0 : title.hashCode());
result = prime * result + ((url == null) ? 0 : url.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Chapter other = (Chapter) obj;
if (title == null) {
if (other.title != null)
return false;
} else if (!title.equals(other.title))
return false;
if (url == null) {
if (other.url != null)
return false;
} else if (!url.equals(other.url))
return false;
return true;
}
@Override
public String toString() {
return "Chapter [title=" + title + ", url=" + url + "]";
}
}
2、编写章节接口 IChapterSpider.java
package novel.spider.interfaces;
import java.util.List;
import novel.spider.model.Chapter;
/**
* 小说章节接口
* @author luohong
* @date 2017年2月12日
*/
public interface IChapterSpider {
/**
* 获取章节列表方法
* @param url 小说url
* @return
*/
public List<Chapter> getChapter(String url);
}
3、编写抽象类AbstractChapterSpider.java
package novel.spider.impl;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import novel.spider.interfaces.IChapterSpider;
import novel.spider.model.Chapter;
/**
* 抽象类
*
* @author luohong
* @date 2017年2月12日
*/
public class AbstractChapterSpider implements IChapterSpider {
/**
* 抓取数据方法
*
* @param url 抓取链接
* @return
* @throws Exception
*/
protected String crawl(String url) throws Exception {
// 通过HttpClientBuilder返回httpClient实体
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build();
CloseableHttpResponse httpResponse = httpClient.execute(new HttpGet(url))) {
// 获取抓取结果
String result = EntityUtils.toString(httpResponse.getEntity());
return result;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public List<Chapter> getChapter(String url) {
try {
String result = crawl(url);
//System.out.println(url);
//System.out.println(result);
/**
* Jsoup解析、Document选择器
*/
Document document = Jsoup.parse(result,"utf-8");
Elements elements = document.select("#list dd a");
List<Chapter> chapters = new ArrayList<>();
for(Element element:elements){
Chapter chapter = new Chapter();
/**
* <a style="" href="/86_86745/4504833.html">第一章 沙漠中的彼岸花</a>
*/
chapter.setTitle(element.text());
chapter.setUrl(url+element.attr("href"));
chapters.add(chapter);
}
return chapters;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
4、编写实现类DefaultChapterSpider.java
package novel.spider.impl;
/**
* 实现类
* @author luohong
* @date 2017年2月12日
*/
public class DefaultChapterSpider extends AbstractChapterSpider{
}
5、编写测试工具类TestCase
package novel.spider.junit;
import java.util.List;
import org.junit.Test;
import novel.spider.impl.DefaultChapterSpider;
import novel.spider.interfaces.IChapterSpider;
import novel.spider.model.Chapter;
/**
* 测试工具类
* @author luohong
* @date 2017年2月12日
*/
public class TestCase {
@Test
public void test1() throws Exception{
IChapterSpider spider = new DefaultChapterSpider();
List<Chapter> chapters = spider.getChapter("http://www.biquge.tw/86_86745/");
for(Chapter chapter:chapters){
System.out.println(chapter);
}
}
}
测试
上面测试类用的地址是
http://www.biquge.tw/86_86745/
右击TestCase.java的test1()方法,选择Run As –>Junit Test 开始测试
控制台输出如下
看到能抓取数据粗来,好开心,就先到这吧。。。后面还会继续学习,再见!
border="0" width="298" height="52" src="//music.163.com/outchain/player?type=2&id=36102163&auto=1&height=32">