上一篇博客我们简单的了解了一波爬虫,知道了什么是爬虫,爬虫的作用,下面我们就开始着手自己来创建一个爬虫。(项目源码估计你们得看最后的几个博客,因为我这个是一边写代码一边写博客的,所以说没有办法那么快提供给大家源码,但是可以先提供 Git 地址)

项目源码 Git 地址:lemon1234_scraper: 一个基于 htmlunit 的 Java 爬虫项目(无页面版,有需要的同学可以自己 clone 下来后进行二开)。本项目切记慎用(请求频率过高,近乎DDOS的请求频率,一旦造成服务器瘫痪,约等于网络攻击),仅供学习使用~~~https://gitee.com/soul-sys/lemon1234_scraper

一、项目需求

简单说一下我们这个项目是干啥的,不了到最后做完也不知道干了点啥,那不完蛋?

我这里是想通过爬虫采集一些博客的数据,采集好数据之后,想着后期把这些采集到的数据都扔在 es 里(es:elasticsearch,一种分布式全文搜索引擎,可以自行了解),然后通过页面搜索关键字,找到一些自己想要的数据。

当然,光采集博客数据还不能满足自己,为了能更好的摸鱼,我还打算爬一些轻小说、短文章的数据,将这些数据采集到本地,然后有时间可以慢慢看。

但是!!!我们这里先不涉及到 es,这个东西我最近在研究,等研究到差不多的时候我会出专门的博客去讲述。

等到项目做完的时候,大家也就学的差不多了,到时候项目可以自己去进行配置,自己选择一些可以爬取的网站进行爬取一些简单的数据。

二、项目框架选择

我们爬虫项目主要基于 SpringBoot 框架,ORM 选择的是 MyBatis-Plus,爬虫我们使用的是 htmlunit。

这里主要说一下为啥用 htmlunit。我之前看过很多的爬虫框架,像 selenium、WebMagic、httpclient+jsoup 等等,很多很多,但是为啥选择了 htmlunit,这里要说一下。

比如 selenium,这个是由 Google 的很多大佬参与开发的一个产品,我们可以用它直接通过程序打开 Chrome 浏览器,然后页面会根据我们的程序自己去操作,当然,在操作的途中我们也可以获取到浏览器中的数据。但是这个玩意也是有坑的,效率贼慢,因为它是靠着浏览器驱动运行的,所以说这玩意不适合我们的项目,我们是定时爬取一大堆数据,就凭借它的效率,可以说直接凉凉。但是它也不是没有优点,selenium 几乎可以说是能爬到任何数据,只要你能用浏览器打开的页面,它都可以爬到该页面的数据。

再有就是 WebMagic 和 httpclient + jsoup 了。

先说 WebMagic,WebMagic 是一个简单灵活的Java爬虫框架,我们可以基于 WebMagic,快速地开发出一个高效、易维护的爬虫。但是为啥我们不用它呢?原因很简单,这玩意爬取不到由 js 加载的数据。我们很多页面,都是一个静态页面,然后里面的一些数据呢,是通过 js 请求后,拿到数据渲染到页面上的,类似这样的页面,WebMagic 可以说直接跪倒在地。

httpclient + jsoup 他俩虽说学起来很容易,运行速度也很快,API 也很简单,但是他俩和 WebMagic 一样,都有一个通病,就是拿不到由 js 加载的数据。

而我们选择的这个 htmlunit 可以说是比较完美了,它是一个没有界面的浏览器,通过模拟浏览器运行,拿到由 js 加载的数据后,返回给我们,然后我们再通过对页面的分析拿到我们所需要的数据,再进行后续操作,而且 API 接口啥的也比较简单易学,这也是我们选择它的原因。

三、项目搭建 & 测试运行

项目名称:

lemon1234_scraper

版本介绍:

  • MySQL 版本:8.0.27(这个版本不强求,你自己会用啥数据库就用啥数据库,那怕存到 derby、h2 都行)
  • SpringBoot 版本:2.7.0(这个同样不强求,我这里一般都是用最新的 SpringBoot~)
  • htmlunit 版本:2.61.0(这个建议是和我的一样,因为版本高了低了可能会存在差异)

pom.xml:

这里我们除去必须要引入的,还引入了 thymeleaf,这里主要是为了后面二开的同学,省的自己再去找模板引擎

<properties><java.version>1.8</java.version><druid.version>1.1.12</druid.version><mybatis.version>2.1.4</mybatis.version><mybatis_plus.version>3.4.1</mybatis_plus.version><fastjson.version>1.2.78</fastjson.version><hutool.version>5.3.0</hutool.version><htmlunit.version>2.61.0</htmlunit.version><jsoup.version>1.15.1</jsoup.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>${mybatis.version}</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>${mybatis_plus.version}</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>${druid.version}</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>${fastjson.version}</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>${hutool.version}</version></dependency><dependency><groupId>net.sourceforge.htmlunit</groupId><artifactId>htmlunit</artifactId></dependency><dependency><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId><version>${jsoup.version}</version></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-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency></dependencies>

application.yml:

这里根据自己的环境去配置就好了,如果不会 MyBatis-plus,建议去它官网简单看看学一学,不是很难。

server:port: 80servlet:context-path: /tomcat:uri-encoding: UTF-8spring:application:name: lemon1234_scraperdatasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/lemon1234_scraper?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghaiusername: rootpassword: 123456dbcp2:min-idle: 5initial-size: 5max-total: 100max-wait-millis: 1000# Mybatis-plus相关配置
mybatis-plus:global-config:db-config:id-type: UUIDtable-prefix: t_lemon1234_scraper_configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImplmap-underscore-to-camel-case: false

logback-spring.xml

我这里日志用的是 logback,当然,你要用别的也行,无所谓的,有个能记录日志的就行。日志等级是 info。

<?xml version="1.0" encoding="UTF-8"?>
<configuration  scan="true" scanPeriod="10 seconds"><contextName>logback</contextName><!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 --><property name="log.path" value="../logs" /><!-- 日志输出格式 --><property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" /><!--输出到控制台--><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>${log.pattern}</pattern><charset>UTF-8</charset></encoder></appender><!-- 时间滚动输出 level为 DEBUG 日志 --><appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 正在记录的日志文件的路径及文件名 --><file>${log.path}/log_debug.log</file><!--日志文件输出格式--><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern><charset>UTF-8</charset> <!-- 设置字符集 --></encoder><!-- 日志记录器的滚动策略,按日期,按大小记录 --><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!-- 日志归档 --><fileNamePattern>${log.path}/debug/log-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>100MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy><!--日志文件保留天数--><maxHistory>15</maxHistory></rollingPolicy><!-- 此日志文件只记录debug级别的 --><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>debug</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><!-- 时间滚动输出 level为 INFO 日志 --><appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 正在记录的日志文件的路径及文件名 --><file>${log.path}/log_info.log</file><!--日志文件输出格式--><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern><charset>UTF-8</charset></encoder><!-- 日志记录器的滚动策略,按日期,按大小记录 --><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!-- 每天日志归档路径以及格式 --><fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>100MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy><!--日志文件保留天数--><maxHistory>15</maxHistory></rollingPolicy><!-- 此日志文件只记录info级别的 --><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>info</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><!-- 时间滚动输出 level为 WARN 日志 --><appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 正在记录的日志文件的路径及文件名 --><file>${log.path}/log_warn.log</file><!--日志文件输出格式--><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern><charset>UTF-8</charset> <!-- 此处设置字符集 --></encoder><!-- 日志记录器的滚动策略,按日期,按大小记录 --><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>100MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy><!--日志文件保留天数--><maxHistory>15</maxHistory></rollingPolicy><!-- 此日志文件只记录warn级别的 --><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>warn</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><!-- 时间滚动输出 level为 ERROR 日志 --><appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 正在记录的日志文件的路径及文件名 --><file>${log.path}/log_error.log</file><!--日志文件输出格式--><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern><charset>UTF-8</charset> <!-- 此处设置字符集 --></encoder><!-- 日志记录器的滚动策略,按日期,按大小记录 --><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>100MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy><!--日志文件保留天数--><maxHistory>15</maxHistory></rollingPolicy><!-- 此日志文件只记录ERROR级别的 --><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>ERROR</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><root level="info"><appender-ref ref="CONSOLE" /><appender-ref ref="DEBUG_FILE" /><appender-ref ref="INFO_FILE" /><appender-ref ref="WARN_FILE" /><appender-ref ref="ERROR_FILE" /></root>
</configuration>

测试:

测试前我们将数据库创建好,别因为连接不上数据库最后报错。

我这里启动有两个 WARN,简单解释一下。

第一个 WARN:因为我们现在项目里面除去这些配置,屁的代码都没有写,所以说像 MyBatis 的 mapper 啥的根本都没有,不报错才怪,等后面加上就没事了。

第二个 WARN:这里是因为我们引入了 thymeleaf 所导致的,如果不想看这个错误,可以去 resources 目录下创建一个 templates 的目录就行。

自己动动手,把项目创建好,等下一讲我们来设计一下表。


这一讲就讲到这里,有问题可以联系我:QQ 2100363119,欢迎大家访问我的个人网站:https://www.lemon1234.com

手把手Java爬虫教学 - 2. 爬虫项目创建 需求说明相关推荐

  1. python反反爬虫教学_爬虫进阶:反反爬虫技巧

    主要针对以下四种反爬技术:Useragent过滤:模糊的Javascript重定向:验证码:请求头一致性检查. 高级网络爬虫技术:绕过 "403 Forbidden",验证码等 爬 ...

  2. src下创建java文件_Eclipse下maven项目创建src/main/java 源文件夹报错文件文件已存在问题...

    标签: 一:选定: 二  选择jre system library选项 三  选择修改jre到默认 修改过后,应该就会自动补充了确实的文件了. 附加: src/main/java      存放项目的 ...

  3. apache目录 vscode_VsCode搭建Java开发环境(Spring Boot项目创建、运行、调试)

    VsCode搭建Java开发环境(Spring Boot项目创建.运行.调试) 安装如下两个主要扩展即可,这两个扩展已关联java项目开发主要使用的maven.springboot等所需要的扩展. 开 ...

  4. [附源码]计算机毕业设计JAVA教师教学评价系统

    [附源码]计算机毕业设计JAVA教师教学评价系统 项目运行 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(Inte ...

  5. Java使用Jsoup写爬虫

    Java使用Jsoup写爬虫 安装Jsoup.jar 简单了解Jsoup Jsoup框架中的常用方法 动手实践 进阶写法 安装Jsoup.jar 1.首先我们打开Jsoup官网 2.按照图片这里下载 ...

  6. 视频教程-手把手带你学会python爬虫-Python

    手把手带你学会python爬虫 曾在某大型公司大型互联网任职多年,在公司主要从事移动端开发.全栈开发.主要技术栈是Android.Java.Python.爬虫.Linux等等. 赵庆元 ¥99.00 ...

  7. 手把手教你入门Python爬虫(二)

    手把手教你入门Python爬虫 前言   在上一篇文章中,我们讲解到了基础的计算机网络知识,并完成了"爬取豆瓣Top250电影信息"的项目.那么这一次,作者将带领大家完成" ...

  8. Java 多线程爬虫及分布式爬虫架构探索

    维护待采集的 URL 多线程爬虫程序就不能像单线程那样,每个线程独自维护这自己的待采集 URL,如果这样的话,那么每个线程采集的网页将是一样的,你这就不是多线程采集啦,你这是将一个页面采集的多次.基于 ...

  9. python爬虫教程pdf-《Python爬虫开发与项目实战》pdf完整版

    [实例简介] [实例截图] [核心代码] 目录 前言 基础篇 第1章 回顾Python编程2 1.1 安装Python2 1.1.1 Windows上安装Python2 1.1.2 Ubuntu上的P ...

最新文章

  1. spring boot打jar包发布
  2. MyBatis中使用#{}和${}的区别
  3. PC网页实现九宫格切图功能
  4. nssl1322,jzoj(初中)2109-清兵线【dp】
  5. boost序列化(Serialization)
  6. AngularJS track by $index引起的思考
  7. NSString (NSStringPathExtensions) 类的相关方法和属性梳理
  8. (一) Windows环境下的Detours编译
  9. 在定语从句中which和that用法有什么区别
  10. 如何设计出一个比较合理的数据归档系统
  11. 抖音特效专场PR模板 Premiere视频转场过渡快速切换画面视频模板下载
  12. mysql中like与rlike_Hive中rlike,like,notlike区别及使用
  13. Android8.0以上,打开uiautomatorviewer.bat,报错Unexpected error while obtaining Ul hierarchy
  14. Android通知不显示横幅的一个坑
  15. pcb只开窗不镀锡_关于pads中 PCB铺铜开窗镀锡 的操作
  16. 大一第一学期期末C语言程序设计笔记(五)
  17. 私域社交电商一站式解决方案,软件开发+供应链服务支持一件代发
  18. 「企业架构」企业架构师的TOGAF的权威指南
  19. 数据表(一) - 数据表的种类
  20. 计算机磁盘的管理实验总结,[计算机]磁盘管理实验报告.doc

热门文章

  1. C10:Unity3D制作智能家居设计软件——三步实现家具生长动画
  2. Minimap2:三代比对工具
  3. 基于basys2驱动LCDQC12864B的verilog设计图片显示
  4. 32位单片机STM32F7外扩QSPI SRAM芯片
  5. Helmet-wearing Datasets
  6. 如何理解产品的海关编码(HS Code),编码归类的主要依据是什么?
  7. Python实现 七段数码管绘制(嵩天老师)
  8. java files.readalllines_java实用类Files详解
  9. 腾讯智慧校园 php,【腾讯智慧校园V1.50】发版
  10. 龙芯胡伟武要当CEO