上一篇:深夜看了张一鸣的微博,让我越想越后怕

来源:www.jianshu.com/p/cfead4b3e34e

WebMagic是一个开源的java爬虫框架。

WebMagic框架的使用并不是本文的重点,具体如何使用请参考官方文档:http://webmagic.io/docs/。

本文是对spring boot+WebMagic+MyBatis做了整合,使用WebMagic爬取数据,然后通过MyBatis持久化爬取的数据到mysql数据库。

本文提供的源代码可以作为java爬虫项目的脚手架。

1.添加maven依赖

<?xml version="1.0" encoding="UTF-8"?>
<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>hyzx</groupId><artifactId>qbasic-crawler</artifactId><version>1.0.0</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.5.21.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.test.skip>true</maven.test.skip><java.version>1.8</java.version><maven.compiler.plugin.version>3.8.1</maven.compiler.plugin.version><maven.resources.plugin.version>3.1.0</maven.resources.plugin.version><mysql.connector.version>5.1.47</mysql.connector.version><druid.spring.boot.starter.version>1.1.17</druid.spring.boot.starter.version><mybatis.spring.boot.starter.version>1.3.4</mybatis.spring.boot.starter.version><fastjson.version>1.2.58</fastjson.version><commons.lang3.version>3.9</commons.lang3.version><joda.time.version>2.10.2</joda.time.version><webmagic.core.version>0.7.3</webmagic.core.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.connector.version}</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>${druid.spring.boot.starter.version}</version></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>${mybatis.spring.boot.starter.version}</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>${fastjson.version}</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>${commons.lang3.version}</version></dependency><dependency><groupId>joda-time</groupId><artifactId>joda-time</artifactId><version>${joda.time.version}</version></dependency><dependency><groupId>us.codecraft</groupId><artifactId>webmagic-core</artifactId><version>${webmagic.core.version}</version><exclusions><exclusion><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId></exclusion></exclusions></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>${maven.compiler.plugin.version}</version><configuration><source>${java.version}</source><target>${java.version}</target><encoding>${project.build.sourceEncoding}</encoding></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-resources-plugin</artifactId><version>${maven.resources.plugin.version}</version><configuration><encoding>${project.build.sourceEncoding}</encoding></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><fork>true</fork><addResources>true</addResources></configuration><executions><execution><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build><repositories><repository><id>public</id><name>aliyun nexus</name><url>http://maven.aliyun.com/nexus/content/groups/public/</url><releases><enabled>true</enabled></releases></repository></repositories><pluginRepositories><pluginRepository><id>public</id><name>aliyun nexus</name><url>http://maven.aliyun.com/nexus/content/groups/public/</url><releases><enabled>true</enabled></releases><snapshots><enabled>false</enabled></snapshots></pluginRepository></pluginRepositories>
</project>

2.项目配置文件 application.properties

配置mysql数据源,druid数据库连接池以及MyBatis的mapper文件的位置。

# mysql数据源配置
spring.datasource.name=mysql
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://192.168.0.63:3306/gjhzjl?useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true
spring.datasource.username=root
spring.datasource.password=root# druid数据库连接池配置
spring.datasource.druid.initial-size=5
spring.datasource.druid.min-idle=5
spring.datasource.druid.max-active=10
spring.datasource.druid.max-wait=60000
spring.datasource.druid.validation-query=SELECT 1 FROM DUAL
spring.datasource.druid.test-on-borrow=false
spring.datasource.druid.test-on-return=false
spring.datasource.druid.test-while-idle=true
spring.datasource.druid.time-between-eviction-runs-millis=60000
spring.datasource.druid.min-evictable-idle-time-millis=300000
spring.datasource.druid.max-evictable-idle-time-millis=600000# mybatis配置
mybatis.mapperLocations=classpath:mapper/**/*.xml

3.数据库表结构

CREATE TABLE `cms_content` (`contentId` varchar(40) NOT NULL COMMENT '内容ID',`title` varchar(150) NOT NULL COMMENT '标题',`content` longtext COMMENT '文章内容',`releaseDate` datetime NOT NULL COMMENT '发布日期',PRIMARY KEY (`contentId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='CMS内容表';

4.实体类

import java.util.Date;public class CmsContentPO {private String contentId;private String title;private String content;private Date releaseDate;public String getContentId() {return contentId;}public void setContentId(String contentId) {this.contentId = contentId;}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;}public Date getReleaseDate() {return releaseDate;}public void setReleaseDate(Date releaseDate) {this.releaseDate = releaseDate;}
}

5.mapper接口

public interface CrawlerMapper {int addCmsContent(CmsContentPO record);
}

6.CrawlerMapper.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hyzx.qbasic.dao.CrawlerMapper"><insert id="addCmsContent" parameterType="com.hyzx.qbasic.model.CmsContentPO">insert into cms_content (contentId,title,releaseDate,content)values (#{contentId,jdbcType=VARCHAR},#{title,jdbcType=VARCHAR},#{releaseDate,jdbcType=TIMESTAMP},#{content,jdbcType=LONGVARCHAR})</insert>
</mapper>

7.XXX页面内容处理类XXXPageProcessor

主要用于解析爬取到的XXX html页面。

@Component
public class XXXPageProcessor implements PageProcessor {private Site site = Site.me().setRetryTimes(3).setSleepTime(1000);@Overridepublic void process(Page page) {page.addTargetRequests(page.getHtml().links().regex("https://www\\.xxx\\.com/question/\\d+/answer/\\d+.*").all());page.putField("title", page.getHtml().xpath("//h1[@class='QuestionHeader-title']/text()").toString());page.putField("answer", page.getHtml().xpath("//div[@class='QuestionAnswer-content']/tidyText()").toString());if (page.getResultItems().get("title") == null) {// 如果是列表页,跳过此页,pipeline不进行后续处理page.setSkip(true);}}@Overridepublic Site getSite() {return site;}
}

8.XXX数据处理类XXXPipeline

主要用于将XXX html页面解析出的数据存储到mysql数据库。另外,MySQL 系列面试题和答案全部整理好了,微信搜索互联网架构师,在后台发送:2T,可以在线阅读。

@Component
public class XXXPipeline implements Pipeline {private static final Logger LOGGER = LoggerFactory.getLogger(XXXPipeline.class);@Autowiredprivate CrawlerMapper crawlerMapper;public void process(ResultItems resultItems, Task task) {String title = resultItems.get("title");String answer = resultItems.get("answer");CmsContentPO contentPO = new CmsContentPO();contentPO.setContentId(UUID.randomUUID().toString());contentPO.setTitle(title);contentPO.setReleaseDate(new Date());contentPO.setContent(answer);try {boolean success = crawlerMapper.addCmsContent(contentPO) > 0;LOGGER.info("保存文章成功:{}", title);} catch (Exception ex) {LOGGER.error("保存文章失败", ex);}}
}

9.爬虫任务类XXXTask

每十分钟启动一次爬虫。

@Component
public class XXXTask {private static final Logger LOGGER = LoggerFactory.getLogger(XXXPipeline.class);@Autowiredprivate XXXPipeline XXXPipeline;@Autowiredprivate XXXPageProcessor xxxPageProcessor;private ScheduledExecutorService timer = Executors.newSingleThreadScheduledExecutor();public void crawl() {// 定时任务,每10分钟爬取一次timer.scheduleWithFixedDelay(() -> {Thread.currentThread().setName("xxxCrawlerThread");try {Spider.create(xxxPageProcessor)// 从https://www.xxx.com/explore开始抓.addUrl("https://www.xxx.com/explore")// 抓取到的数据存数据库.addPipeline(xxxPipeline)// 开启2个线程抓取.thread(2)// 异步启动爬虫.start();} catch (Exception ex) {LOGGER.error("定时抓取数据线程执行异常", ex);}}, 0, 10, TimeUnit.MINUTES);}
}

10.Spring boot程序启动类

@SpringBootApplication
@MapperScan(basePackages = "com.hyzx.qbasic.dao")
public class Application implements CommandLineRunner {@Autowiredprivate XXXTask xxxTask;public static void main(String[] args) throws IOException {SpringApplication.run(Application.class, args);}@Overridepublic void run(String... strings) throws Exception {// 爬取数据xxxTask.crawl();}
}

感谢您的阅读,也欢迎您发表关于这篇文章的任何建议,关注我,技术不迷茫!小编到你上高速。

· END ·

最后,关注公众号互联网架构师,在后台回复:2T,可以获取我整理的 Java 系列面试题和答案,非常齐全。

正文结束

推荐阅读 ↓↓↓

1.不认命,从10年流水线工人,到谷歌上班的程序媛,一位湖南妹子的励志故事

2.如何才能成为优秀的架构师?

3.从零开始搭建创业公司后台技术栈

4.程序员一般可以从什么平台接私活?

5.37岁程序员被裁,120天没找到工作,无奈去小公司,结果懵了...

6.IntelliJ IDEA 2019.3 首个最新访问版本发布,新特性抢先看

7.这封“领导痛批95后下属”的邮件,句句扎心!

8.15张图看懂瞎忙和高效的区别!

一个人学习、工作很迷茫?

点击「阅读原文」加入我们的小圈子!

Spring Boot + WebMagic 实现网页爬虫,写得太好了!相关推荐

  1. 深入理解 Spring Boot Starters 原理(手写Spring boot Start)

    一.Spring Boot Starter诞生原因 Spring Boot Starter是在SpringBoot组件中被提出来的一种概念,stackoverflow上面已经有人概括了这个starte ...

  2. Spring Boot + Dataway :接口不用写,配配就出来?

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 作者 | 哈库纳 来源 | my.oschina.net ...

  3. Spring Boot 开发web网页(helloworld为例)

    Spring Boot 开发入门--- helloworld web 一.使用IntellijIDEA建立第一个spring boot 项目(helloworld) 1.创建一个spring boot ...

  4. Spring Cloud 如何统一异常处理?写得太好了!

    欢迎关注方志朋的博客,回复"666"获面试宝典 作者:BNDong 链接:www.cnblogs.com/bndong/p/10135370.html 前言 在启动应用时会发现在控 ...

  5. Spring Boot 实现扫码登录,这种方式太香了!!

    作者 | 93年颈椎病人 来源 | https://blog.csdn.net/q826qq1878/article/details/91041679 最近有个项目涉及到websocket实现扫码登录 ...

  6. Spring Boot 实现扫码登录,这种方式太香了

    开发者(KaiFaX) 面向全栈工程师的开发者 专注于前端.Java/Python/Go/PHP的技术社区 来源 https://blog.csdn.net/q826qq1878/article/de ...

  7. 关于spring boot集成MQTT的一写新人问题

    这几天弄了下mqtt ,发现有很多问题,网上搜不到什么解决办法,所以自己记录下来,也让初识mqtt的人少走一些坑,关于我写的不对的也希望看到的人能指出来互相学习下 安装 说到mqtt,首先肯定要安装了 ...

  8. 利用Spring Boot WebMagic MyBatis 爬数据并存入mysql

    一.  WebMagic简介 webmagic是一个开源的Java垂直爬虫框架,目标是简化爬虫的开发流程,让开发者专注于逻辑功能的开发.webmagic的核心非常简单,但是覆盖爬虫的整个流程,也是很好 ...

  9. Spring Boot WebMagic 入库时 mapper注入提示空指针,以及正确的操作

    本屌研究了一整天 网上说 实现Pipeline接口中的 process是多线程的,所以注入后不是同一个对象,无所报空指针 贴出代码 1.启动类 @SpringBootApplication @Enab ...

  10. Spring Boot开发简单网页(员工管理系统)(四):国际化

    国际化 1.编码格式 2.编写配置文件 3.配置国际化资源文件 4.中英文切换 国际化,也就是页面可以进行中英文切换 1.编码格式 首先需要保证项目所有的编码格式都是UTF-8 2.编写配置文件 在s ...

最新文章

  1. 一文带你读懂Python的5大特点与8大应用方向!
  2. 一位产品总监打算这样管国家:首先得让大家交得起税。
  3. 从权限管理看互联网产品的盈利方式
  4. 使用Node.JS监听文件夹变化
  5. Html之图片轮播(锚)
  6. 【操作系统】SPOOLing技术(外部设备联机并行操作/假脱机技术)
  7. printf的输出格式
  8. 如何批量查询ip地址归属地等信息?
  9. 单测量矢量多目标精确DOA估计的高效稀疏表示算法
  10. hmcl启动器怎么联机_HMCL 启动器教程 #1 安装启动器
  11. 计算机科学环境保护,计算机在环保领域中的应用
  12. python推箱子游戏代码_推箱子游戏,推箱子游戏代码python实现
  13. SSH移植到arm开发板
  14. 运动神经元病是怎么回事?
  15. 关于自己配置电脑的一点心得
  16. 弗雷德里克·特曼:硅谷之父、斯坦福大学前副校长——(转自新浪网)
  17. R语言 PDF文件损坏或打不开
  18. java常用文件工具类
  19. cubemax设置中断优先级
  20. 语音识别—实现百度语音识别

热门文章

  1. CSS按钮动画(五)
  2. 如何利用Camtasia给视频加上配音?
  3. scss转换成css,hotcss
  4. nodejs基础 -- 全局对象
  5. js中的empty()和remove()的区别
  6. 解决异常:公共语言运行时检测到无效的程序
  7. 管理 ciner-volumes
  8. LA 2218 Triathlon (Geometry, Half Plane Intersection)
  9. 祝愿父亲节里的父亲们快乐!
  10. MindNode 5 for Mac(思维导图)中文版