《花100块做个摸鱼小网站! 》第二篇—后端应用搭建和完成第一个爬虫
一、前言
大家好呀,我是summo,前面已经教会大家怎么去阿里云买服务器(链接在这,需要自取:https://developer.aliyun.com/huodong/dashiblogger?userCode=mtbtcjr1),以及怎么搭建JDK、Redis、MySQL这些环境或者数据库。从这篇文章开始就进入正式的编码阶段了,我们从后端开始,先把热搜数据获取到,然后再开始前端部分。
本来我想把后端应用搭建和完成第一个爬虫分为两篇文章写的,但是想到墨迹三周还没看到效果,估计有些同学已经等不及了,所以我把这两篇文章合成一篇了,篇幅比较长,感兴趣的同学可以认真看下。因为后端应用初始化的时候涉及很多配置,有很多命名,建议大家写别急着个性化用自己的名字命名应用和配置,可以先用我的命名方式搭建一个出来,先成功再研究个性化,这样成就感很足,学习动力也强。
二、后端应用搭建
这个摸鱼小网站主要使用的SpringBoot框架配合一些中间件实现,开发工具用的是idea社区版,建议不要下载人家的正式版然后破解,一来麻烦的很,二来社区版足够开发使用了,点击这个可以下载idea社区版。
1. maven项目搭建
打开idea后,点击New Project,我们从一个空的maven项目开始,一步步把项目搭建出来。

我们输入name、GroupId、ArtifactId点击确定,如果你是老手可以自己搭建,如果你是新手建议跟我输的一样,因为后面还有很多地方要用的这些名字。

把src目录删掉,我们不需要,只留下pom.xml文件就行了。

接下来我们开始创建子module,创建方式如下图:

以summo-sbmy-start子module为例,输入如下的信息就可以创建一个module出来啦。

按照这个方式创建出如下的module出来。

2. pom.xml配置
这部分我现在不详细说,后面我会单独写一篇文章讲我的依赖和配置。如果刚才你的名字取得跟我一样,直接复制粘贴就完事了,如果名字不一样记得把名字给替换为你的。
(1)summo-sbmy
pom.xml内容如下:
<?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><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.15</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.summo</groupId><artifactId>summo-sbmy</artifactId><packaging>pom</packaging><version>1.0-SNAPSHOT</version><modules><module>summo-sbmy-dao</module><module>summo-sbmy-service</module><module>summo-sbmy-web</module><module>summo-sbmy-start</module><module>summo-sbmy-job</module><module>summo-sbmy-common</module></modules><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencyManagement><dependencies><!-- 自依赖 --><dependency><groupId>com.summo</groupId><artifactId>summo-sbmy-common</artifactId><version>${project.version}</version></dependency><dependency><groupId>com.summo</groupId><artifactId>summo-sbmy-service</artifactId><version>${project.version}</version></dependency><dependency><groupId>com.summo</groupId><artifactId>summo-sbmy-common</artifactId><version>${project.version}</version></dependency><dependency><groupId>com.summo</groupId><artifactId>summo-sbmy-dao</artifactId><version>${project.version}</version></dependency><dependency><groupId>com.summo</groupId><artifactId>summo-sbmy-job</artifactId><version>${project.version}</version></dependency><dependency><groupId>com.summo</groupId><artifactId>summo-sbmy-start</artifactId><version>${project.version}</version></dependency><dependency><groupId>com.summo</groupId><artifactId>summo-sbmy-web</artifactId><version>${project.version}</version></dependency><!-- xxl-job --><dependency><groupId>com.xuxueli</groupId><artifactId>xxl-job-core</artifactId><version>2.2.0</version></dependency><!-- MySQL驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.20</version></dependency><!-- mybatis-plus驱动 --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.3.2</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-extension</artifactId><version>3.3.2</version></dependency><!-- 分页插件 --><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>1.4.1</version></dependency><!-- lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.16.22</version></dependency><!-- druid链接池 --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.22</version></dependency><!-- aspectj --><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.5</version></dependency><!-- fastjson --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>2.0.21</version></dependency><!-- 线程上下文 --><dependency><groupId>com.alibaba</groupId><artifactId>transmittable-thread-local</artifactId><version>2.11.1</version></dependency><!-- 接口参数校验 --><dependency><groupId>javax.validation</groupId><artifactId>validation-api</artifactId><version>2.0.1.Final</version></dependency><!-- Redisson分布式锁 --><dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.24.0</version></dependency><!-- 通用工具类 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.5</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-collections4</artifactId><version>4.1</version></dependency><!-- VM 模板 --><dependency><groupId>com.alibaba.boot</groupId><artifactId>velocity-spring-boot-starter</artifactId><version>1.0.4.RELEASE</version></dependency><!-- guava --><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>32.1.1-jre</version></dependency><!-- httpclient --><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpcore</artifactId><version>4.4.16</version></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.14</version></dependency><!-- jsoup --><dependency><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId><version>1.12.1</version></dependency><!-- ip2region  --><dependency><groupId>org.lionsoul</groupId><artifactId>ip2region</artifactId><version>2.6.3</version></dependency><!-- 用于读取ip2region.xdb文件使用 --><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.6</version></dependency><!-- 加解密代码--><dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId><version>1.68</version></dependency><dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId><version>1.15</version></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>1.8</source><target>1.8</target><encoding>utf-8</encoding></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-source-plugin</artifactId><version>2.2</version><executions><execution><id>attach-sources</id><goals><goal>jar</goal></goals></execution></executions><configuration><finalName>${project.build.finalName}</finalName></configuration></plugin></plugins></build>
</project>
 
(2)summo-sbmy-start
pom.xml内容如下:
<?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"><parent><artifactId>summo-sbmy</artifactId><groupId>com.summo</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>summo-sbmy-start</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><dependency><groupId>com.summo</groupId><artifactId>summo-sbmy-service</artifactId></dependency><dependency><groupId>com.summo</groupId><artifactId>summo-sbmy-job</artifactId></dependency><dependency><groupId>com.summo</groupId><artifactId>summo-sbmy-dao</artifactId></dependency><dependency><groupId>com.summo</groupId><artifactId>summo-sbmy-common</artifactId></dependency><dependency><groupId>com.summo</groupId><artifactId>summo-sbmy-web</artifactId></dependency><!-- 测试组件 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><scope>test</scope></dependency></dependencies><!-- 添加四个环境的变量,变量名为environment --><profiles><profile><id>test</id><activation><activeByDefault>true</activeByDefault></activation><properties><environment>test</environment></properties></profile><profile><id>consumer</id><properties><environment>consumer</environment></properties></profile><profile><id>producer</id><properties><environment>producer</environment></properties></profile></profiles><build><finalName>summo-sbmy</finalName><resources><resource><!-- 指定配置文件所在的resource目录 --><directory>src/main/resources</directory><includes><include>application.properties</include><include>logback-spring.xml</include><include>**/*.html</include><include>**/*.js</include><include>**/*.css</include></includes><filtering>true</filtering></resource><resource><!-- 指定配置文件所在的resource目录 --><directory>src/main/resources</directory><includes><include>**/*.woff</include><include>**/*.ttf</include><include>**/*.xdb</include><include>**/*.jks</include></includes><filtering>false</filtering></resource></resources><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.1.13.RELEASE</version><executions><execution><goals><goal>repackage</goal></goals></execution></executions><configuration><mainClass>com.summo.sbmy.Application</mainClass></configuration></plugin><!-- 解压fat jar到target/${project-name}目录 --><plugin><artifactId>maven-antrun-plugin</artifactId><executions><execution><phase>package</phase><configuration><target><unzipsrc="${project.build.directory}/${project.build.finalName}.${project.packaging}"dest="${project.build.directory}/summo-sbmy"/></target></configuration><goals><goal>run</goal></goals></execution></executions></plugin></plugins></build>
</project> 
(3)summo-sbmy-common
pom.xml内容如下:
<?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"><parent><artifactId>summo-sbmy</artifactId><groupId>com.summo</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>summo-sbmy-common</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><!-- SpringBoot框架 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!-- aspectj --><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.5</version></dependency><!-- logback核心组件 --><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-core</artifactId></dependency><!-- fastjson --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId></dependency><!-- 线程上下文 --><dependency><groupId>com.alibaba</groupId><artifactId>transmittable-thread-local</artifactId></dependency><!-- 分页插件 --><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>1.4.1</version></dependency><!-- 接口参数校验 --><dependency><groupId>javax.validation</groupId><artifactId>validation-api</artifactId></dependency><dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId></dependency><!-- Redis框架 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- Redisson分布式锁 --><dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId></dependency><!-- jedisÏ分布式锁 --><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId></dependency><!-- 通用工具类 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-collections4</artifactId></dependency><!-- guava --><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId></dependency><!-- httpclient --><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpcore</artifactId></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId></dependency><dependency><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId></dependency><!-- ip2region  --><dependency><groupId>org.lionsoul</groupId><artifactId>ip2region</artifactId></dependency><!-- 用于读取ip2region.xdb文件使用 --><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId></dependency><!-- 加解密代码 --><dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId></dependency><dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId></dependency><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.8.6</version></dependency></dependencies>
</project> 
(4)summo-sbmy-dao
pom.xml内容如下:
<?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"><parent><artifactId>summo-sbmy</artifactId><groupId>com.summo</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>summo-sbmy-dao</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><dependency><groupId>com.summo</groupId><artifactId>summo-sbmy-common</artifactId></dependency><!-- MySQL驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!-- mybatis-plus驱动 --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-extension</artifactId></dependency><dependency><groupId>javax.persistence</groupId><artifactId>javax.persistence-api</artifactId></dependency><!-- druid链接池 --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><version>1.3.6</version><configuration><configurationFile>${basedir}/src/main/resources/generator/generatorConfiguration.xml</configurationFile><overwrite>true</overwrite><verbose>true</verbose></configuration><dependencies><dependency><groupId>tk.mybatis</groupId><artifactId>mapper</artifactId><version>4.1.2</version></dependency></dependencies></plugin></plugins></build>
</project> 
(5)summo-sbmy-service
pom.xml内容如下:
<?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"><parent><artifactId>summo-sbmy</artifactId><groupId>com.summo</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>summo-sbmy-service</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><dependency><groupId>com.summo</groupId><artifactId>summo-sbmy-dao</artifactId></dependency></dependencies>
</project> 
(7)summo-sbmy-web
pom.xml内容如下:
<?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"><parent><artifactId>summo-sbmy</artifactId><groupId>com.summo</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>summo-sbmy-web</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><dependency><groupId>com.summo</groupId><artifactId>summo-sbmy-service</artifactId></dependency><!-- thymeleaf --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency></dependencies>
</project>
 
pom.xml配置贴好后,更新一下,把依赖包都下载下来。如果你发现下载的非常慢,把maven仓库的镜像换一下,换成阿里云的。镜像配置如下:
<mirrors><mirror><id>alimaven</id><mirrorOf>central</mirrorOf><name>aliyun maven</name><url>https://maven.aliyun.com/repository/public</url></mirror>
</mirrors>
 
3. application.properties配置
## 应用名
spring.application.name=summo-sbmy
## 端口号
server.port=8080# 配置Druid数据源类型
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
# 数据库连接URL,包括数据库名、允许的公开密钥检索、字符编码、禁用SSL、时区设置等
spring.datasource.url=jdbc:mysql://xxx:3306/summo-sbmy?allowPublicKeyRetrieval=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true&zeroDateTimeBehavior=convertToNull
# 数据库用户名
spring.datasource.username=xxx
# 数据库密码
spring.datasource.password=xxx
# 数据库驱动类名
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 初始化连接池时创建的连接数量
spring.datasource.druid.initial-size=5
# 连接池最大活跃连接数
spring.datasource.druid.max-active=30
# 连接池最小空闲连接数
spring.datasource.druid.min-idle=5
# 等待连接获取的最大等待时间
spring.datasource.druid.max-wait=60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接
spring.datasource.druid.time-between-eviction-runs-millis=60000
# 配置一个连接在池中最小生存的时间
spring.datasource.druid.min-evictable-idle-time-millis=300000
# 验证数据库连接有效的SQL语句
spring.datasource.druid.validation-query=SELECT 1 FROM DUAL
# 是否在从连接池获取连接前进行检验(建议关闭,影响性能)
spring.datasource.druid.test-while-idle=true
# 获取连接时执行validationQuery检测连接是否有效(建议关闭,影响性能)
spring.datasource.druid.test-on-borrow=false
# 归还连接时执行validationQuery检测连接是否有效(建议关闭,影响性能)
spring.datasource.druid.test-on-return=false
# 是否开启PSCache(PreparedStatement缓存),默认false
spring.datasource.druid.pool-prepared-statements=false
# 指定每个连接上PSCache的大小,默认-1表示不限制
spring.datasource.druid.max-pool-prepared-statement-per-connection-size=0
# 启用监控统计和日志过滤器
spring.datasource.druid.filters=stat,wall
# 配置StatFilter的参数,合并SQL记录
spring.datasource.druid.connection-properties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
# 是否合并Druid数据源的监控信息
spring.datasource.druid.use-global-data-source-stat=true
# 开启Wall过滤器,并指定数据库类型为MySQL
spring.datasource.druid.filter.wall.enabled=true
spring.datasource.druid.filter.wall.db-type=mysql
# 配置StatFilter的数据库类型为MySQL
spring.datasource.druid.filter.stat.db-type=mysql
# 开启StatFilter
spring.datasource.druid.filter.stat.enabled=true# MyBatis配置:自动映射行为设置为全字段
mybatis.configuration.auto-mapping-behavior=full
# MyBatis配置:下划线转驼峰命名规则
mybatis.configuration.map-underscore-to-camel-case=true
# MyBatis-Plus的Mapper文件位置
mybatis-plus.mapper-locations=classpath*:/mybatis/mapper/*.xml# Redis数据库索引
spring.redis.database=0
# Redis连接超时时间(毫秒)
spring.redis.timeout=1800000
# Redis服务器地址
spring.redis.host=127.0.0.1
# Redis服务器端口
spring.redis.port=6379
# Redis服务器连接密码
spring.redis.password=xxx
# 使用Lettuce连接池时的最大等待时间(-1表示无限制)
spring.redis.lettuce.pool.max-wait=-1
# Lettuce连接池的最大空闲连接数
spring.redis.lettuce.pool.max-idle=5
# Lettuce连接池的最小空闲连接数
spring.redis.lettuce.pool.min-idle=0
# Lettuce连接池的最大活跃连接数
spring.redis.lettuce.pool.max-active=20
# 使用Jedis连接池时的最小空闲连接数
spring.redis.jedis.pool.min-idle=8
# Jedis连接池的最大空闲连接数
spring.redis.jedis.pool.max-idle=500
# Jedis连接池的最大活跃连接数
spring.redis.jedis.pool.max-active=2000
# Jedis连接池的最大等待时间(毫秒)
spring.redis.jedis.pool.max-wait=10000 
4. logback-spring.xml配置
<configuration><!-- 默认的一些配置 --><include resource="org/springframework/boot/logging/logback/defaults.xml"/><!-- 定义应用名称,区分应用 --><property name="APP_NAME" value="summo-sbmy"/><!-- 定义日志文件的输出路径 --><property name="LOG_PATH" value="${user.home}/logs/${APP_NAME}"/><!-- 定义日志文件名称和路径 --><property name="LOG_FILE" value="${LOG_PATH}/application.log"/><!-- 定义警告级别日志文件名称和路径 --><property name="WARN_LOG_FILE" value="${LOG_PATH}/warn.log"/><!-- 定义错误级别日志文件名称和路径 --><property name="ERROR_LOG_FILE" value="${LOG_PATH}/error.log"/><!-- 自定义控制台打印格式 --><property name="FILE_LOG_PATTERN" value="%green(%d{yyyy-MM-dd HH:mm:ss.SSS}) [%blue(requestId: %X{requestId})] [%highlight(%thread)] ${PID:- } %logger{36} %-5level - %msg%n"/><!-- 将日志滚动输出到application.log文件中 --><appender name="APPLICATION"class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 输出文件目的地 --><file>${LOG_FILE}</file><encoder><pattern>${FILE_LOG_PATTERN}</pattern><charset>utf8</charset></encoder><!-- 设置 RollingPolicy 属性,用于配置文件大小限制,保留天数、文件名格式 --><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><!-- 文件命名格式 --><fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.%i.log</fileNamePattern><!-- 文件保留最大天数 --><maxHistory>7</maxHistory><!-- 文件大小限制 --><maxFileSize>50MB</maxFileSize><!-- 文件总大小 --><totalSizeCap>500MB</totalSizeCap></rollingPolicy></appender><!-- 摘取出WARN级别日志输出到warn.log中 --><appender name="WARN" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${WARN_LOG_FILE}</file><encoder><!-- 使用默认的输出格式打印 --><pattern>${CONSOLE_LOG_PATTERN}</pattern><charset>utf8</charset></encoder><!-- 设置 RollingPolicy 属性,用于配置文件大小限制,保留天数、文件名格式 --><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><!-- 文件命名格式 --><fileNamePattern>${LOG_PATH}/warn.%d{yyyy-MM-dd}.%i.log</fileNamePattern><!-- 文件保留最大天数 --><maxHistory>7</maxHistory><!-- 文件大小限制 --><maxFileSize>50MB</maxFileSize><!-- 文件总大小 --><totalSizeCap>500MB</totalSizeCap></rollingPolicy><!-- 日志过滤器,将WARN相关日志过滤出来 --><filter class="ch.qos.logback.classic.filter.ThresholdFilter"><level>WARN</level></filter></appender><!-- 摘取出ERROR级别日志输出到error.log中 --><appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${ERROR_LOG_FILE}</file><encoder><!-- 使用默认的输出格式打印 --><pattern>${CONSOLE_LOG_PATTERN}</pattern><charset>utf8</charset></encoder><!-- 设置 RollingPolicy 属性,用于配置文件大小限制,保留天数、文件名格式 --><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><!-- 文件命名格式 --><fileNamePattern>${LOG_PATH}/error.%d{yyyy-MM-dd}.%i.log</fileNamePattern><!-- 文件保留最大天数 --><maxHistory>7</maxHistory><!-- 文件大小限制 --><maxFileSize>50MB</maxFileSize><!-- 文件总大小 --><totalSizeCap>500MB</totalSizeCap></rollingPolicy><!-- 日志过滤器,将ERROR相关日志过滤出来 --><filter class="ch.qos.logback.classic.filter.ThresholdFilter"><level>ERROR</level></filter></appender><!-- 配置控制台输出 --><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>${FILE_LOG_PATTERN}</pattern><charset>utf8</charset></encoder></appender><!-- 配置输出级别 --><root level="INFO"><!-- 加入控制台输出 --><appender-ref ref="CONSOLE"/><!-- 加入APPLICATION输出 --><appender-ref ref="APPLICATION"/><!-- 加入WARN日志输出 --><appender-ref ref="WARN"/><!-- 加入ERROR日志输出 --><appender-ref ref="ERROR"/></root>
</configuration>
 
5. 创建启动类
package com.summo.sbmy;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;/*** @author summo* @version Application.java, 1.0.0* @description 启动核心类* @date 2024年08月09*/
@SpringBootApplication(scanBasePackages = {"com.summo.sbmy"})
@EnableScheduling
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}} 
点击启动,打印如下就算成功
 
三、实现抖音热搜爬虫
第一次写爬虫代码,我们找一个最简单,也是最安全的例子,抖音热搜。
 
1. 爬虫方案评估
为什么简单?
 它就一个接口:https://www.iesdouyin.com/web/api/v2/hotsearch/billboard/word/,免登录也不需要参数,你们直接在浏览器上调用就可以把抖音的热搜数据获取到了;
为什么安全?
 调用https://www.iesdouyin.com/robots.txt接口,返回如下:
User-agent: *
Allow: /Sitemap: http://www.iesdouyin.com/sitemap/index.xml
 
这个代表什么呢?
 
看到了吗,人家不仅允许你去爬,还提供了网站地图的链接,这也是他们为了提高谷歌、必应、百度等浏览器的收录的一种办法。所以,不用担心爬这些数据会怎么样了。
2. 获取链接的cURL代码
先上一张图,如下:

大概的步骤如下:
- 输入https://www.iesdouyin.com/web/api/v2/hotsearch/billboard/word/链接,按下enter;
 - 打开控制台,选择【全部】找到刚才调用的接口;
 - 选中接口,右键打开菜单,选择复制里面的“以cURL格式复制”这一项。
 
复制出来是这样的东西
curl 'https://www.iesdouyin.com/web/api/v2/hotsearch/billboard/word/' \-H 'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7' \-H 'accept-language: zh-CN,zh;q=0.9' \-H 'cache-control: no-cache' \-H 'cookie: ttwid=1%7CJ6ehEognyMAob_gD6oZwA40monN8E_sENr3IUZmuk7o%7C1712472728%7C44b0cd0003fb75861789d62e56f014eaea3d198898a0ae9a947bf61d95d8ac1a; __ac_signature=_02B4Z6wo00f01fFoqvgAAIDBFmj97SX8qiXxSK5AABr708; __ac_referer=https://pre-dc-console.alibaba-inc.com/' \-H 'pragma: no-cache' \-H 'priority: u=0, i' \-H 'sec-ch-ua: "Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"' \-H 'sec-ch-ua-mobile: ?0' \-H 'sec-ch-ua-platform: "macOS"' \-H 'sec-fetch-dest: document' \-H 'sec-fetch-mode: navigate' \-H 'sec-fetch-site: none' \-H 'sec-fetch-user: ?1' \-H 'upgrade-insecure-requests: 1' \-H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36'
 
能看懂吗?能看懂最好,看不懂也没有关系,不是给我们看的,给Postman看的。Postman是一个http接口调用工具非常好用,电脑上没有Postman的同学就去下载一个。
3. 使用Postman生成调用代码
打开你的Postman软件,按照我下面这张图操作:
 
按照我上面的步骤,将cURL命令导入Postman,可以快速生成一个调用请求,如下图:

这个方式也可以用在我们平时调试接口,比如说有一个接口报错了,需要不断地叫前端重试一下,再重试一下,非常麻烦。这个时候你就可以叫前端把这个cURL复制给你,自己动手重试,就不用麻烦别人啦。

在Postman的右上角有一个Code snippet,可以直接生成你想要的调用代码,啥Java、Python、NodeJs都有,不用自己写,复制就可以运行。咋样,Postman没有白骗你下载吧!

代码如下
OkHttpClient client = new OkHttpClient().newBuilder().build();
Request request = new Request.Builder().url("https://www.iesdouyin.com/web/api/v2/hotsearch/billboard/word/").method("GET", null).addHeader("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7").addHeader("accept-language", "zh-CN,zh;q=0.9").addHeader("cache-control", "no-cache").addHeader("cookie", "ttwid=1%7CJ6ehEognyMAob_gD6oZwA40monN8E_sENr3IUZmuk7o%7C1712472728%7C44b0cd0003fb75861789d62e56f014eaea3d198898a0ae9a947bf61d95d8ac1a; __ac_signature=_02B4Z6wo00f01fFoqvgAAIDBFmj97SX8qiXxSK5AABr708; __ac_referer=https://pre-dc-console.alibaba-inc.com/; ttwid=1%7CX9ppA_NoTHJI9DG3JN7wNnZ662r-aJbZwCFPLLGK-og%7C1713836331%7Cdbc79a439d0ecc994f60043d66b4ad3ff81c3820f3ab83ef85d30875cc59a18b").addHeader("pragma", "no-cache").addHeader("priority", "u=0, i").addHeader("sec-ch-ua", "\"Not/A)Brand\";v=\"8\", \"Chromium\";v=\"126\", \"Google Chrome\";v=\"126\"").addHeader("sec-ch-ua-mobile", "?0").addHeader("sec-ch-ua-platform", "\"macOS\"").addHeader("sec-fetch-dest", "document").addHeader("sec-fetch-mode", "navigate").addHeader("sec-fetch-site", "none").addHeader("sec-fetch-user", "?1").addHeader("upgrade-insecure-requests", "1").addHeader("user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36").build();
Response response = client.newCall(request).execute();
 
4. 将代码迁移到应用中
在summo-sbmy-job这个module下,创建一个文件夹com.summo.sbmy.job.douyin,创建DouyinHotSearchJob.java,代码如下
package com.summo.sbmy.job.douyin;import java.io.IOException;import com.alibaba.fastjson.JSONObject;import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;/*** @author summo* @version DouyinHotSearchJob.java, 1.0.0* @description 抖音热搜Java爬虫代码* @date 2024年08月09*/
@Component
public class DouyinHotSearchJob {/*** 定时触发爬虫方法,1个小时执行一次*/@Scheduled(fixedRate = 1000 * 60 * 60)public void hotSearch() throws IOException {OkHttpClient client = new OkHttpClient().newBuilder().build();Request request = new Request.Builder().url("https://www.iesdouyin.com/web/api/v2/hotsearch/billboard/word/").method("GET", null).addHeader("accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;"+ "q=0.8,application/signed-exchange;v=b3;q=0.7").addHeader("accept-language", "zh-CN,zh;q=0.9").addHeader("cache-control", "no-cache").addHeader("cookie","ttwid=1%7CJ6ehEognyMAob_gD6oZwA40monN8E_sENr3IUZmuk7o%7C1712472728"+ "%7C44b0cd0003fb75861789d62e56f014eaea3d198898a0ae9a947bf61d95d8ac1a; "+ "__ac_signature=_02B4Z6wo00f01fFoqvgAAIDBFmj97SX8qiXxSK5AABr708; "+ "__ac_referer=https://pre-dc-console.alibaba-inc.com/; "+ "ttwid=1%7CX9ppA_NoTHJI9DG3JN7wNnZ662r-aJbZwCFPLLGK-og%7C1713836331"+ "%7Cdbc79a439d0ecc994f60043d66b4ad3ff81c3820f3ab83ef85d30875cc59a18b").addHeader("pragma", "no-cache").addHeader("priority", "u=0, i").addHeader("sec-ch-ua", "\"Not/A)Brand\";v=\"8\", \"Chromium\";v=\"126\", \"Google Chrome\";v=\"126\"").addHeader("sec-ch-ua-mobile", "?0").addHeader("sec-ch-ua-platform", "\"macOS\"").addHeader("sec-fetch-dest", "document").addHeader("sec-fetch-mode", "navigate").addHeader("sec-fetch-site", "none").addHeader("sec-fetch-user", "?1").addHeader("upgrade-insecure-requests", "1").addHeader("user-agent","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) "+ "Chrome/126.0.0.0 Safari/537.36").build();Response response = client.newCall(request).execute();System.out.println(JSONObject.toJSONString(response.body().string()));}}
 
这个爬虫代码会在启动的时候执行一次,然后每一小时执行一次。这样,我们的第一个定时爬虫就做好了。如果以上的内容你都看不懂,那就直接复制我这代码吧,鱼和渔都给你了。
四、小结一下
这一篇配置文件很多,篇幅很长,大家要耐心和细心一些,不然很容易出错。这里给出的配置是按照最终版给的,到时开发的时候不用担心少依赖或者少包,至于原理和选型后面再单独说吧。我觉得看一个Java程序员经验丰不丰富从他搭建的脚手架就可以看出来,因为脚手架不像代码一样有标准,它是由框架和插件构成的,适合你就用,没有什么是必须的。
还有就是爬虫,可能有些同学会失望,这玩意咋这么简单,一点技术含量都没有。简单的原因一是热搜接口都是免登无校验的,二是因为我已经给你们趟了一条路出来,饭喂到嘴里了。后面还有很多热搜爬虫,有些也挺麻烦的,不用急,我会慢慢公布。
 大多数同学大多数时间都只是在干CRUD的活,也没有独立建站的经验,虽然没有但是可以学!现在不会练练就会!100块钱的实操经验绝对比100块钱买的专栏更有意义更有用!
最后,自建摸鱼网站,各大网站热搜一览,上班和摸鱼很配哦!
相关文章:
《花100块做个摸鱼小网站! 》第二篇—后端应用搭建和完成第一个爬虫
一、前言 大家好呀,我是summo,前面已经教会大家怎么去阿里云买服务器(链接在这,需要自取:https://developer.aliyun.com/huodong/dashiblogger?userCodemtbtcjr1),以及怎么搭建JDK、Redis、My…...
Mapreduce_csv_averageCSV文件计算平均值
csv文件求某个平均数据 查询每个部门的平均工资,最后输出 数据处理过程 employee_noheader.csv(没做关于首行的处理,运行时请自行删除) EmployeeID,EmployeeName,DepartmentID,Salary 1,ZhangSan,101,5000 2,LiSi,102,6000…...
将UEC++项目转码成UTF-8
方法一 如果文件不多的话,可以手动一个一个进行修改。添加 “高级保存选项” 手动改为UTF-8 方法二 使用editorconfig文件,统一编码问题。通过:“工具” > “选项”>"文本编辑器" > "C/C" > "代码样式…...
深入探索MySQL C API:使用C语言操作MySQL数据库
目录 引言 一. MySQL C API简介 二. MySQL C API核心函数 2.1 初始化和连接 2.2 配置和执行 2.3 处理结果 2.4 清理和关闭 2.5 错误处理 三. MySQL使用过程 四. 实现CRUD操作 4.1 创建数据库并建立表 编辑 4.2 添加数据(Create) 编辑 …...
武汉流星汇聚:亚马逊助力跨境电商扬帆起航,海外影响力显著提升
在全球化浪潮的推动下,跨境电商已成为连接世界市场的重要桥梁。而在这场跨越国界的商业盛宴中,亚马逊作为全球电商的领军者,以其独特的商业模式、庞大的用户基础,为无数企业提供了前所未有的发展机遇。武汉流星汇聚电子商务有限公…...
C语言:设计模式
C语言和设计模式(总结篇) 书籍:《大话设计模式》 2、C语言和设计模式:原型模式(复制自己,生成另外一个实例对象) 17、C语言实现面向对象编程 : 封装、继承、多态 ---- C语言可:封…...
Pandas数据选择的艺术:深入理解loc和iloc
在数据科学领域,Pandas是处理和分析数据的瑞士军刀。掌握Pandas中的数据选择技巧,尤其是loc和iloc的使用,对于提高数据处理效率至关重要。本文将深入探讨loc和iloc的用法,通过丰富的示例,帮助你精确地选取所需的数据&a…...
<数据集>固定视角监控牧场绵羊识别数据集<目标检测>
数据集格式:VOCYOLO格式 图片数量:3615张 标注数量(xml文件个数):3615 标注数量(txt文件个数):3615 标注类别数:1 标注类别名称:[Sheep] 序号类别名称图片数框数1Sheep361529632 使用标注工具&#…...
浙大数据结构慕课课后题(06-图2 Saving James Bond - Easy Version)(拯救007)
题目要求: This time let us consider the situation in the movie "Live and Let Die" in which James Bond, the worlds most famous spy, was captured by a group of drug dealers. He was sent to a small piece of land at the center of a lake fi…...
前置(1):npn 和yarn ,pnpm安装依赖都是从那个源安装的啊,有啥优缺点呢
在使用 npm、yarn 或 pnpm 进行依赖管理和安装时,它们通常默认从 npm 的公共仓库(https://registry.npmjs.org/)获取包。不过,用户可以配置它们以从其他源获取,例如企业内部的私有仓库或镜像站点(如淘宝的 …...
视频融合项目中的平台抉择:6大关键要素助力精准选型
随着安防监控系统行业的快速发展,视频融合项目逐渐成为城市治理、企业管理及智能建筑等领域的重要组成部分。视频融合平台作为视频数据整合、管理和分析的核心,其选择直接影响到项目的成功与否。 在当前智慧业务类项目的集成过程中,我们不仅…...
微信小程序项目结构
微信小程序的项目结构相对清晰,主要包括以下几个部分: 一、项目根目录文件 app.js:小程序项目的入口文件,通过调用App()函数来启动整个小程序的生命周期。这个文件包含了小程序的全局数据、生命周期函数等。 app.json:…...
C++unordered_map的用法
unordered_map的简介 unordered_map是一种容器,可以把字符串当做数字,可以使用[]操作符来访问key值对应的值。 格式: unordered_map<要被转换的类型,转换的类型> 变量名{{要被转换的数或字符,转换的数或字符}}/…...
代码随想录算法训练营第三十六天| 188.买卖股票的最佳时机IV、309.最佳买卖股票时机含冷冻期、714.买卖股票的最佳时机含手续费
写代码的第三十六天 买股票,卡卡买股票,就爱买股票。。。 188.买卖股票的最佳时机IV 思路 本题是多次进行买卖,所以根据上题进行修改。 解决问题1:dp数组的含义以及定义?上题定义的事dp[i][0]初始状态,dp[i][1]第一…...
Golang | Leetcode Golang题解之第332题重新安排行程
题目: 题解: func findItinerary(tickets [][]string) []string {var (m map[string][]string{}res []string)for _, ticket : range tickets {src, dst : ticket[0], ticket[1]m[src] append(m[src], dst)}for key : range m {sort.Strings(m[key])…...
Spring Boot - 通过ServletRequestHandledEvent事件实现接口请求的性能监控
文章目录 概述1. ServletRequestHandledEvent事件2. 实现步骤3. 优缺点分析4. 测试与验证小结其他方案1. 自定义拦截器2. 性能监控平台3. 使用Spring Boot Actuator4. APM工具 概述 在Spring框架中,监控接口请求的性能可以通过ServletRequestHandledEvent事件实现。…...
Docker相关配置记录
Docker相关配置记录 换源 {"registry-mirrors": ["https://dockerhub.icu","https://docker.chenby.cn","https://docker.1panel.live","https://docker.awsl9527.cn","https://docker.anyhub.us.kg","htt…...
MySQL中INT(3)与INT(11)
本文由 ChatMoney团队出品 开篇 在MySQL数据库设计的世界里,数据类型的选择是一项基础而又至关重要的任务。其中,INT数据类型因其广泛的应用和灵活性备受青睐。然而,围绕着INT(3)与INT(11)的具体差异,常常存在一些误解。本文旨在…...
Qt 窗口:菜单、工具与状态栏的应用
目录 引言: 1. 菜单栏 1.1 创建菜单栏 1.2 在菜单栏中添加菜单 1.3 创建菜单项 1.4 在菜单项之间添加分割线 1.5 综合示例 2.工具栏 2.1 创建工具栏 2.2 设置停靠位置 2.3 设置浮动属性 2.4 设置移动属性 3. 状态栏 3.1 状态栏的创建 3.2 在状态栏中显…...
学习必备好物有哪些?高三开学季好物推荐合集
新学期即将开启,学习必备好物有哪些?以下是特别为高三学生朋友们精心挑选的一系列好物推荐,旨在帮助大家在更快更好的选择,快来看看都有哪些吧! 1、书客护眼大路灯Sun 书客是海内外知名的生物光学技术方案商…...
vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的
修改bug思路: 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑:async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...
MFC 抛体运动模拟:常见问题解决与界面美化
在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...
Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
Bean 作用域有哪些?如何答出技术深度?
导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答,…...
「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案
在移动互联网营销竞争白热化的当下,推客小程序系统凭借其裂变传播、精准营销等特性,成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径,助力开发者打造具有市场竞争力的营销工具。 一、系统核心功能架构&…...
通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器
拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件: 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...
