java爬虫抓取动态网页(本文将介绍如何使用SeimiCrawler将页面中信息提取为结构化数据并存储到数据库中)
优采云 发布时间: 2021-10-21 10:05java爬虫抓取动态网页(本文将介绍如何使用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,可以下载,自己试试,直接点击。
文章链接:[](转载请注明本文出处及链接文章)