java古诗_java抓取古诗文的单线程爬虫

本文介绍了一个使用Java编写的单线程爬虫,用于抓取古诗文网站上的唐诗链接及内容。通过Jsoup库解析HTML,正则表达式处理数据,实现了从获取页面到解析出每首诗的详细信息的完整流程。爬虫首先获取Document对象,然后解析出所有唐诗的href,接着从这些链接中抓取每首诗的作者、朝代和内容,并最终将数据存储到MySQL数据库中。
摘要由CSDN通过智能技术生成

准备知识

1.HTML, CSS, HTML DOM树

参考http://www.w3school.com.cn/htmldom/

2.Jsoup的使用,使用DOM方法遍历一个document对象,使用选择器语法来选择一个元素,从元素中抽取数据。

参考www.open-open.com/jsoup/example-list-links.htm

3.java正则表达式及其语法

参考http://www.cnblogs.com/chuiyuan/p/5187359.html

我们先来做一个单线程的爬虫。

整体步骤:

1.定义爬取内容的对象Poem结构。

2.完成从网上爬取Document对象的模块HttpService功能。

3.从Document对象中解析出所有唐诗的href,并保存到List中。

4.从3中得到的href再爬取出每首古诗的内容。

下面帖一下代码实现。

1.Poem对象只列出其属性

f52efa02cd0a32c78b5ed7851410ab66.png

2.抓取Document对象模块HttpService

首先定义一个Rule,封装所有的请求,不管是get还是post。

8e67dc0e9c0c856d39870ec56d868fd7.png

在HttpService中,使用Rule来抓取document对象。

/**

* Created by chuiyuan on 2/11/16.

*/

public class HttpService {

/**

*

* @param rule

* @return doc

*/

public Document extrace(Rule rule){

validateRule(rule);

String url = rule.getUrl();

String [] params = rule.getParams() ;

String [] values = rule.getValues() ;

String resultTagName = rule.getResultTagName() ;

int type = rule.getType();

int requestMethod = rule.getRequestMethod() ;

Document doc =null ;

try {

Connection conn = Jsoup.connect(url);

conn.userAgent("Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0 Iceweasel/38.5.0");

if (params!= null){

for (int i =0; i

conn.data(params[i], values[i]);

}

}

//Document doc = null ;

switch (requestMethod){

case Rule.GET:

doc =conn.timeout(10000).get();

break;

case Rule.POST:

doc =conn.timeout(10000).post();

break;

}

}catch (IOException e ){

System.out.println("No network");

//e.printStackTrace();

}

return doc ;

}

/**

* validate input params

*/

private static void validateRule(Rule rule){

String url = rule.getUrl() ;

if (url == null || url.length()==0){

throw new RuleException("url can't be null");

}

if (!url.startsWith("http://")){

throw new RuleException("url not in correct format");

}

/**

* not consider total right

*/

if (rule.getParams()!= null && rule.getValues()!= null){

if (rule.getParams().length!= rule.getValues().length){

throw new RuleException("params length!= values length");

}

}

}

}

可以看到,我们先对rule进行了验证,rule中的resultTagName并没有用到,可以去掉。

3.从Document中解析出所有唐诗的href

4.从每首诗文的href中提到详细的内容

public class ProcessDoc {

/**

*

* @param url

* @param httpService

* @return List

*/

public List processGuShiWen(String url, HttpService httpService ){

Rule rule = new Rule(url,

null,null,

null,

-1,

Rule.GET);

Document doc = httpService.extrace(rule);

if (doc == null){

System.out.println("doc null");

return null;

}

//left panel

Elements mainEles = doc.select("div.leftlei");

//String dynasty = mainEles.select("div.son1").first().text();

Elements poemsEles = mainEles.select("div.son2");//size=7 category

//System.out.println(poemsEles.size());

List poemList = new ArrayList();

//Pattern p =Pattern.compile("\\(|\\)");

//some times there is no author

for (Element poemsEle : poemsEles){

Elements poemEles = poemsEle.select("span");

String category1 = poemEles.get(0).text(); //category with ":"

String category = category1.substring(0,category1.length()-1);

for (int i =1;i

Poem poem = new Poem() ;

//poem.setDynasty(dynasty);

poem.setCategory(category);

poem.setHref(poemEles.get(i).select("a").attr("abs:href")+"/");//ref

poem.setTitle(poemEles.get(i).select("a").text());

poemList.add(poem);

}

}

/*for (Poem poem : poemList){

System.out.println(poem.getCategory()+

" "+poem.getTitle()+

" "+poem.getHref());

}*/

return poemList ;

}

/**

* get details of poem

* @param poem

* @param httpService

*/

public void processDetails(Poem poem, HttpService httpService ){

String url = poem.getHref() ;

//System.out.println(url);

Rule rule = new Rule(url,

null,null,

null,

-1,

Rule.GET);

Document doc = httpService.extrace(rule);

if (doc == null) {

System.out.println("doc=null");

return;

}

Elements mainEles = doc.select("div.son2");

//title already ok

Elements poemDetailEles = mainEles.select("p");

String dynasty = poemDetailEles.get(0).text().split(":")[1];//note,chinese :

//Stng dynasty = poemDetailEles.get(0).getElementsByTag("span").text();

//System.out.println(dynasty);

String author = poemDetailEles.get(1).getElementsByTag("a").text();

//System.out.println(author);

String content = mainEles.text().split("原文:")[1];//note

//System.out.println(content);

//do not consider translation

//Element translationEle = doc.select("#")

poem.setDynasty(dynasty);

poem.setAuthor(author);

poem.setContent(content);

//System.out.println(poem.toString());

}

}

整体调用如下

/**

* single thread model,

* save to mysql

*/

public void getGuShiWenSingleThread(){

String url ="http://so.gushiwen.org/gushi/tangshi.aspx/";

HttpService httpService = new HttpService();

ProcessDoc processDoc= new ProcessDoc();

List poemList = processDoc.processGuShiWen(url, httpService);

//get poem content details

for (Poem poem : poemList){

processDoc.processDetails(poem,httpService);

System.out.println(poem.toString());

}

//store to mysql

PoemDao poemDao = new PoemDaoImpl() ;//not PoemDaoImpl

for (Poem poem: poemList){

try {

poemDao.add(poem);

}catch (SQLException e){

e.printStackTrace();

}

}

}

最后结果保存到了MySQL中,数据库部分将在下一篇文章中讲解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值