java爬虫抓取动态网页(本文将介绍如何使用SeimiCrawler将页面中信息提取为结构化数据并存储到数据库中)

优采云 发布时间: 2021-10-21 10:05

  java爬虫抓取动态网页(本文将介绍如何使用SeimiCrawler将页面中信息提取为结构化数据并存储到数据库中)

  本文将介绍如何使用SeimiCrawler将页面中的信息提取成结构化数据并存入数据库,这也是一个非常常见的使用场景。数据抓取将以博客园的博客为例。

  建立基础数据结构

  为了演示,为了简单起见,只创建一个表来存储博客标题和内容这两个主要信息。表格如下:

  CREATE TABLE `blog` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`title` varchar(300) DEFAULT NULL,

`content` text,

`update_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

  同时创建对应的Bean对象,如下:

  package cn.wanghaomiao.model;

import cn.wanghaomiao.seimi.annotation.Xpath;

import org.apache.commons.lang3.StringUtils;

import org.apache.commons.lang3.builder.ToStringBuilder;

/**

* Xpath语法可以参考 http://jsoupxpath.wanghaomiao.cn/

*/

public class BlogContent {

@Xpath("//h1[@class='postTitle']/a/text()|//a[@id='cb_post_title_url']/text()")

private String title;

//也可以这么写 @Xpath("//div[@id='cnblogs_post_body']//text()")

@Xpath("//div[@id='cnblogs_post_body']/allText()")

private String content;

public String getTitle() {

return title;

}

public void setTitle(String title) {

this.title = title;

}

public String getContent() {

return content;

}

public void setContent(String content) {

this.content = content;

}

@Override

public String toString() {

if (StringUtils.isNotBlank(content)&&content.length()>100){

//方便查看截断下

this.content = StringUtils.substring(content,0,100)+"...";

}

return ToStringBuilder.reflectionToString(this);

}

}

  这里的@Xpath 注释应该侧重于介绍。注释配置了对应字段的 XPath 提取规则。后面会介绍,SeimiCrawler会调用Response.render(Class bean)自动解析并填充对应的字段。对于开发者来说,提取结构化数据最重要的工作就在这里,仅此而已,接下来就是如何串连起来。

  实现数据存储

  本文演示了人人网早期开源的ORM框架paoding-jade的使用。由于SeimiCrawler的对象池和依赖管理都是使用spring实现的,所以SeimiCrawler自然支持所有可以和spring集成的ORM框架。

  要启用 Jade,请添加 pom 依赖项:

  

net.paoding

paoding-rose-jade

2.0.u01

org.apache.commons

commons-dbcp2

2.1.1

mysql

mysql-connector-java

5.1.37

  在resources下添加seimi-jade.xml配置文件:

  写DAO,

  package cn.wanghaomiao.dao;

import cn.wanghaomiao.model.BlogContent;

import net.paoding.rose.jade.annotation.DAO;

import net.paoding.rose.jade.annotation.ReturnGeneratedKeys;

import net.paoding.rose.jade.annotation.SQL;

@DAO

public interface StoreToDbDAO {

@ReturnGeneratedKeys

@SQL("insert into blog (title,content,update_time) values (:1.title,:1.content,now())")

public int save(BlogContent blog);

}

  数据存储完成后,下一步就是我们的爬虫规则类。

  履带式

  直接地:

  package cn.wanghaomiao.crawlers;

import cn.wanghaomiao.dao.StoreToDbDAO;

import cn.wanghaomiao.model.BlogContent;

import cn.wanghaomiao.seimi.annotation.Crawler;

import cn.wanghaomiao.seimi.struct.Request;

import cn.wanghaomiao.seimi.struct.Response;

import cn.wanghaomiao.seimi.def.BaseSeimiCrawler;

import cn.wanghaomiao.xpath.model.JXDocument;

import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

/**

* 将解析出来的数据直接存储到数据库中

*/

@Crawler(name = "storedb")

public class DatabaseStoreDemo extends BaseSeimiCrawler {

@Autowired

private StoreToDbDAO storeToDbDAO;

@Override

public String[] startUrls() {

return new String[]{"http://www.cnblogs.com/"};

}

@Override

public void start(Response response) {

JXDocument doc = response.document();

try {

List urls = doc.sel("//a[@class='titlelnk']/@href");

logger.info("{}", urls.size());

for (Object s:urls){

push(Request.build(s.toString(),"renderBean"));

}

} catch (Exception e) {

//ignore

}

}

public void renderBean(Response response){

try {

BlogContent blog = response.render(BlogContent.class);

logger.info("bean resolve res={},url={}",blog,response.getUrl());

//使用神器paoding-jade存储到DB

int blogId = storeToDbDAO.save(blog);

logger.info("store sus,blogId = {}",blogId);

} catch (Exception e) {

//ignore

}

}

}

  Github上也有完整的demo,可以下载,自己试试,直接点击。

  文章链接:[](转载请注明本文出处及链接文章)

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线