《花100塊做個摸魚小網站! 》第二篇—後端應用搭建和完成第一個爬蟲

sum墨發表於2024-08-12

一、前言

大家好呀,我是summo,前面已經教會大家怎麼去阿里雲買伺服器(連結在這,需要自取),以及怎麼搭建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>
                                <unzip
                                        src="${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程式碼

先上一張圖,如下:

大概的步驟如下:

  1. 輸入https://www.iesdouyin.com/web/api/v2/hotsearch/billboard/word/連結,按下enter;
  2. 開啟控制檯,選擇【全部】找到剛才呼叫的介面;
  3. 選中介面,右鍵開啟選單,選擇複製裡面的“以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塊錢買的專欄更有意義更有用!

最後,自建摸魚網站,各大網站熱搜一覽,上班和摸魚很配哦!

相關文章