├── README.md ├── crawler-nodata.sql ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── xmlvhy │ │ └── crawler │ │ ├── CrawlerBsbdjApplication.java │ │ ├── config │ │ ├── MybatisConfig.java │ │ ├── QQConfig.java │ │ └── WeChatConfig.java │ │ ├── constant │ │ └── CommonConstants.java │ │ ├── controller │ │ ├── CrawlerController.java │ │ ├── CrawlerDataManagerController.java │ │ ├── LoginController.java │ │ ├── QQLoginController.java │ │ ├── TestController.java │ │ ├── VerifyCodeController.java │ │ └── WeChatController.java │ │ ├── dao │ │ ├── ChannelMapper.java │ │ ├── CommentMapper.java │ │ ├── ContentMapper.java │ │ ├── CustomerMapper.java │ │ ├── ForumMapper.java │ │ ├── ImageMapper.java │ │ ├── SourceDao.java.bak │ │ ├── SourceMapper.java │ │ ├── UserMapper.java │ │ └── VideoMapper.java │ │ ├── entity │ │ ├── Channel.java │ │ ├── Comment.java │ │ ├── Content.java │ │ ├── Customer.java │ │ ├── Forum.java │ │ ├── Image.java │ │ ├── LayUiResponse.java │ │ ├── ResponseResult.java │ │ ├── Source.java │ │ ├── Source.java.bak │ │ ├── User.java │ │ └── Video.java │ │ ├── exception │ │ ├── CrawlerException.java │ │ └── CrawlerExceptionHandler.java │ │ ├── interceptors │ │ ├── LoginInterceptor.java │ │ └── WebConfig.java │ │ ├── service │ │ ├── ContentService.java │ │ ├── CrawlerService.java │ │ ├── CustomerService.java │ │ ├── DataProcessedService.java │ │ └── impl │ │ │ ├── ContentServiceImpl.java │ │ │ ├── CrawlerServiceImpl.java │ │ │ ├── CustomerServiceImpl.java │ │ │ └── DataProcessedServiceImpl.java │ │ ├── task │ │ └── CrawlerTask.java │ │ ├── utils │ │ ├── CodeUtil.java │ │ ├── CommonUtil.java │ │ ├── HttpUtils.java │ │ ├── JwtUtils.java │ │ ├── OgnlUtil.java │ │ └── QQHttpClientUtil.java │ │ └── vo │ │ └── CustomerVo.java └── resources │ ├── application-dev.properties │ ├── application-pro.properties │ ├── application.properties │ ├── banner.txt │ ├── config.properties │ ├── i18n │ └── messages.properties │ ├── logback-spring.xml │ ├── mybatis │ ├── mapper │ │ ├── ChannelMapper.xml │ │ ├── CommentMapper.xml │ │ ├── ContentMapper.xml │ │ ├── CustomerMapper.xml │ │ ├── ForumMapper.xml │ │ ├── ImageMapper.xml │ │ ├── SourceMapper.xml │ │ ├── SourceMapper.xml.bak │ │ ├── UserMapper.xml │ │ └── VideoMapper.xml │ └── mbg.xml │ ├── static │ ├── css │ │ ├── crawler.css │ │ ├── error.css │ │ ├── font-awesome.min.css │ │ ├── login.css │ │ └── me.css │ ├── favicon.ico │ ├── fonts │ │ ├── FontAwesome.otf │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.svg │ │ ├── fontawesome-webfont.ttf │ │ ├── fontawesome-webfont.woff │ │ └── fontawesome-webfont.woff2 │ ├── images │ │ ├── 404.png │ │ ├── 404_msg.png │ │ ├── 404_to_index.png │ │ ├── error_bg.jpg │ │ ├── error_cloud.png │ │ ├── image.jpg │ │ └── login_bg.jpg │ ├── layui │ │ ├── css │ │ │ ├── layui.css │ │ │ ├── layui.mobile.css │ │ │ └── modules │ │ │ │ ├── code.css │ │ │ │ ├── laydate │ │ │ │ └── default │ │ │ │ │ └── laydate.css │ │ │ │ └── layer │ │ │ │ └── default │ │ │ │ ├── icon-ext.png │ │ │ │ ├── icon.png │ │ │ │ ├── layer.css │ │ │ │ ├── loading-0.gif │ │ │ │ ├── loading-1.gif │ │ │ │ └── loading-2.gif │ │ ├── font │ │ │ ├── iconfont.eot │ │ │ ├── iconfont.svg │ │ │ ├── iconfont.ttf │ │ │ └── iconfont.woff │ │ ├── images │ │ │ └── face │ │ │ │ ├── 0.gif │ │ │ │ ├── 1.gif │ │ │ │ ├── 10.gif │ │ │ │ ├── 11.gif │ │ │ │ ├── 12.gif │ │ │ │ ├── 13.gif │ │ │ │ ├── 14.gif │ │ │ │ ├── 15.gif │ │ │ │ ├── 16.gif │ │ │ │ ├── 17.gif │ │ │ │ ├── 18.gif │ │ │ │ ├── 19.gif │ │ │ │ ├── 2.gif │ │ │ │ ├── 20.gif │ │ │ │ ├── 21.gif │ │ │ │ ├── 22.gif │ │ │ │ ├── 23.gif │ │ │ │ ├── 24.gif │ │ │ │ ├── 25.gif │ │ │ │ ├── 26.gif │ │ │ │ ├── 27.gif │ │ │ │ ├── 28.gif │ │ │ │ ├── 29.gif │ │ │ │ ├── 3.gif │ │ │ │ ├── 30.gif │ │ │ │ ├── 31.gif │ │ │ │ ├── 32.gif │ │ │ │ ├── 33.gif │ │ │ │ ├── 34.gif │ │ │ │ ├── 35.gif │ │ │ │ ├── 36.gif │ │ │ │ ├── 37.gif │ │ │ │ ├── 38.gif │ │ │ │ ├── 39.gif │ │ │ │ ├── 4.gif │ │ │ │ ├── 40.gif │ │ │ │ ├── 41.gif │ │ │ │ ├── 42.gif │ │ │ │ ├── 43.gif │ │ │ │ ├── 44.gif │ │ │ │ ├── 45.gif │ │ │ │ ├── 46.gif │ │ │ │ ├── 47.gif │ │ │ │ ├── 48.gif │ │ │ │ ├── 49.gif │ │ │ │ ├── 5.gif │ │ │ │ ├── 50.gif │ │ │ │ ├── 51.gif │ │ │ │ ├── 52.gif │ │ │ │ ├── 53.gif │ │ │ │ ├── 54.gif │ │ │ │ ├── 55.gif │ │ │ │ ├── 56.gif │ │ │ │ ├── 57.gif │ │ │ │ ├── 58.gif │ │ │ │ ├── 59.gif │ │ │ │ ├── 6.gif │ │ │ │ ├── 60.gif │ │ │ │ ├── 61.gif │ │ │ │ ├── 62.gif │ │ │ │ ├── 63.gif │ │ │ │ ├── 64.gif │ │ │ │ ├── 65.gif │ │ │ │ ├── 66.gif │ │ │ │ ├── 67.gif │ │ │ │ ├── 68.gif │ │ │ │ ├── 69.gif │ │ │ │ ├── 7.gif │ │ │ │ ├── 70.gif │ │ │ │ ├── 71.gif │ │ │ │ ├── 8.gif │ │ │ │ └── 9.gif │ │ ├── lay │ │ │ └── modules │ │ │ │ ├── carousel.js │ │ │ │ ├── code.js │ │ │ │ ├── colorpicker.js │ │ │ │ ├── element.js │ │ │ │ ├── flow.js │ │ │ │ ├── form.js │ │ │ │ ├── jquery.js │ │ │ │ ├── laydate.js │ │ │ │ ├── layedit.js │ │ │ │ ├── layer.js │ │ │ │ ├── laypage.js │ │ │ │ ├── laytpl.js │ │ │ │ ├── mobile.js │ │ │ │ ├── rate.js │ │ │ │ ├── slider.js │ │ │ │ ├── table.js │ │ │ │ ├── tree.js │ │ │ │ ├── upload.js │ │ │ │ └── util.js │ │ ├── layui.all.js │ │ └── layui.js │ └── video │ │ └── login_bg.mov │ ├── templates │ ├── error │ │ ├── 4xx.html │ │ └── 5xx.html │ ├── login.html │ ├── manage_center.html │ ├── preview.html │ └── register.html │ └── trigger.txt └── test └── java └── com └── xmlvhy └── crawler └── CrawlerBsbdjApplicationTests.java /README.md: -------------------------------------------------------------------------------- 1 | **SpringBoot入门爬虫项目实战** 2 | 3 | > 个人博客:[https://www.xmlvhy.com](https://www.xmlvhy.com "https://www.xmlvhy.com"),Java技术交流,技术分享以及经验总结和资源分享。欢迎来访~ 4 | 5 | ##### 一、介绍 6 | 7 | 本项目作为SpringBoot入门实战项目,主要实现异步任务定时爬取**百思不得姐**数据,并将数据解析入库,提供给前端页面展示。前端采用LayUI相关组件,界面算美观。项目代码没有过度封装(注释详细)。对于刚入门SpringBoot的童鞋,上手这个实战项目还是不错的哈~~ 另外,项目还整合了第三方授权登录(QQ和微信),感兴趣的也可以看看。 8 | 9 | ##### 二、技术选型 10 | ###### 2.1、技术组合 11 | - 数据库:Mysql 12 | - 技术组合:SpringBoot、SpringMvc、Mybatis、PageHelper、Thymeleaf 13 | - 前端框架:Layui 14 | - Lombok、okHttp、jwt、gson序列化与反序列化、ognl(对象图导航,简化json对象解析) 15 | - 其它:QQ登录、微信扫码登录 16 | 17 | ##### 三、开发环境 18 | ###### 3.1、工具与环境 19 | - IDEA 2018.3.5 20 | - Maven 3 21 | - JDK8 22 | - Mysql 5.7+ 23 | - Win10 64位系统 24 | 25 | ##### 四、项目演示 26 | 27 | ###### 4.1、相关页面截图 28 | 29 | 1. 注册登录页,管理页面,包括查询、删除、浏览 30 | 31 | ![](http://static.xmlvhy.com/sb-crawler/crawler-login.png) 32 | 33 | ![](http://static.xmlvhy.com/sb-crawler/crawler1.png) 34 | 35 | ![](http://static.xmlvhy.com/sb-crawler/crawler5.png) 36 | 37 | ![](http://static.xmlvhy.com/sb-crawler/crawler4.png) 38 | 39 | 2. 预览页面,基本上将解析的数据,如视频、图片、动态图、文字都展示出来 40 | 41 | ![](http://static.xmlvhy.com/sb-crawler/crawler-video.png) 42 | 43 | ![](http://static.xmlvhy.com/sb-crawler/crawler-gif.png) 44 | 45 | ![](http://static.xmlvhy.com/sb-crawler/crawler-img.png) 46 | 47 | ![](http://static.xmlvhy.com/sb-crawler/crawler-story.png) 48 | 49 | #####五、启动 50 | 51 | - main 方法运行 52 | 53 | ``` 54 | 1. 主配置文件:application.properties,可以选择生效的配置文件(dev,pro),先导入数据库脚本,然后配置你本地数据库的账户密码 55 | 2. 其它配置:config.properties,这个文件主要配置QQ、微信授权登录相关。若使用,需要修改为你相关的信息 56 | 3. com.xmlvhy.crawler.CrawlerBsbdjApplication:主函数入口,点击运行 57 | 4. 访问:http://localhost:8081/crawler 58 | 5. 账户密码:admin/123456 59 | 60 | tips:项目中使用了lombok插件,IDE得装lombok插件 61 | ``` 62 | 63 | **备注:** 64 | 65 | - 项目中用的接口,使用Charles 抓包工具抓取分析获取,接口可能会出现用不了的情况,需要自己抓取分析。但是至今,这几个接口还是可以正常爬取内容的。 66 | - crawler-nodata.sql,数据库脚本是没有任何数据的,因为当前本地数据有几百M大小就不上传了,需要的前往我的 [个人博客](https://www.xmlvhy.com) 留言,打包发给您! 67 | 68 | ##### 特别说明 69 | 70 | **本项目涉及到的内容以及数据仅供学习交流使用,不得用以其它非法用途!!!** 71 | 72 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.4.RELEASE 9 | 10 | 11 | com.xmlvhy 12 | crawler-bsbdj 13 | 0.0.1-SNAPSHOT 14 | Demo project for Spring Boot 15 | 16 | 17 | 1.8 18 | 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-web 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-thymeleaf 28 | 2.1.4.RELEASE 29 | 30 | 31 | 32 | org.mybatis.spring.boot 33 | mybatis-spring-boot-starter 34 | 2.0.1 35 | 36 | 37 | 38 | mysql 39 | mysql-connector-java 40 | 5.1.47 41 | 42 | 43 | 44 | com.github.pagehelper 45 | pagehelper-spring-boot-starter 46 | 1.2.5 47 | 48 | 49 | 50 | com.alibaba 51 | druid 52 | 1.1.10 53 | 54 | 55 | 56 | 57 | org.springframework.boot 58 | spring-boot-devtools 59 | runtime 60 | 61 | 62 | 63 | org.projectlombok 64 | lombok 65 | true 66 | 67 | 68 | org.springframework.boot 69 | spring-boot-starter-test 70 | test 71 | 72 | 73 | 74 | 75 | 76 | com.google.code.gson 77 | gson 78 | 2.8.9 79 | 80 | 81 | org.apache.httpcomponents 82 | httpclient 83 | 4.5.13 84 | 85 | 86 | 87 | io.jsonwebtoken 88 | jjwt 89 | 0.7.0 90 | 91 | 92 | 93 | com.squareup.okhttp3 94 | okhttp 95 | 3.10.0 96 | 97 | 101 | 102 | ognl 103 | ognl 104 | 3.1.2 105 | 106 | 107 | com.alibaba 108 | fastjson 109 | 1.2.47 110 | 111 | 112 | 113 | 114 | 115 | crawler 116 | 117 | 118 | 119 | org.mybatis.generator 120 | mybatis-generator-maven-plugin 121 | 1.3.5 122 | 123 | 124 | ${project.basedir}/src/main/resources/mybatis/mbg.xml 125 | 126 | true 127 | 128 | true 129 | 130 | 131 | 132 | 133 | mysql 134 | mysql-connector-java 135 | 5.1.47 136 | 137 | 138 | 139 | 140 | org.springframework.boot 141 | spring-boot-maven-plugin 142 | 143 | 144 | 145 | 146 | 147 | -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/CrawlerBsbdjApplication.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.scheduling.annotation.EnableScheduling; 6 | 7 | @SpringBootApplication 8 | @EnableScheduling //开启任务调度,使用定时任务 9 | public class CrawlerBsbdjApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(CrawlerBsbdjApplication.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/config/MybatisConfig.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.config; 2 | 3 | import com.alibaba.druid.pool.DruidDataSource; 4 | import org.mybatis.spring.annotation.MapperScan; 5 | import org.springframework.boot.context.properties.ConfigurationProperties; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.stereotype.Component; 8 | 9 | import javax.sql.DataSource; 10 | 11 | /** 12 | * @ClassName MybatisConfig 13 | * @Description TODO mybatis 的配置类 14 | * @Author 小莫 15 | * @Date 2019/04/09 15:56 16 | * @Version 1.0 17 | **/ 18 | @Component 19 | //扫描dao包,自动生成mapper对应的实现类 20 | @MapperScan("com.xmlvhy.crawler.dao") 21 | public class MybatisConfig { 22 | 23 | /** 24 | *功能描述: 配置阿里的druid连接池 25 | * @Author 小莫 26 | * @Date 16:10 2019/04/09 27 | * @Param [] 28 | * @return javax.sql.DataSource 29 | */ 30 | @Bean 31 | @ConfigurationProperties(prefix = "spring.datasource") 32 | public DataSource dataSource(){ 33 | return new DruidDataSource(); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/config/QQConfig.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.config; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | import org.springframework.beans.factory.annotation.Value; 7 | import org.springframework.context.annotation.Configuration; 8 | 9 | /** 10 | * @ClassName QQConfig 11 | * @Description TODO qq授权相关配置类 12 | * @Author 小莫 13 | * @Date 2019/04/19 13:11 14 | * @Version 1.0 15 | **/ 16 | @Data 17 | @AllArgsConstructor 18 | @NoArgsConstructor 19 | @Configuration 20 | public class QQConfig { 21 | 22 | @Value("${qq.app_id}") 23 | private String appId; 24 | @Value("${qq.app_key}") 25 | private String appKey; 26 | @Value("${qq.redirect_url}") 27 | private String redirectUrl; 28 | @Value("${qq.oauth_url}") 29 | private String oauthUrl; 30 | @Value("${qq.access_token_url}") 31 | private String accessTokenUrl; 32 | @Value("${qq.open_id_url}") 33 | private String openIdUrl; 34 | @Value("${qq.user_info_url}") 35 | private String userInfoUrl; 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/config/WeChatConfig.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.config; 2 | 3 | import lombok.Data; 4 | import org.springframework.beans.factory.annotation.Value; 5 | import org.springframework.context.annotation.PropertySource; 6 | import org.springframework.stereotype.Component; 7 | 8 | /** 9 | * @ClassName WeChatConfig 10 | * @Description TODO 微信配置类 11 | * @Author 小莫 12 | * @Date 2019/04/13 19:40 13 | * @Version 1.0 14 | **/ 15 | @Component 16 | @PropertySource("classpath:config.properties") 17 | @Data 18 | public class WeChatConfig { 19 | /*微信开放平台生成的appId*/ 20 | @Value("${wxopen.appid}") 21 | private String appId; 22 | /*微信开放平台生成的app secret*/ 23 | @Value("${wxopen.appsecret}") 24 | private String appSecret; 25 | /*微信扫码登录回调地址*/ 26 | @Value("${wxopen.redirect_url}") 27 | private String redirectUrl; 28 | /*微信开放平台二维码连接*/ 29 | @Value("${wxopen.qrcode_url}") 30 | public String openQRCodeUrl; 31 | /*微信开放平台获取access_token地址*/ 32 | @Value("${wxopen.access_token_url}") 33 | public String accessTokenUrl; 34 | /*获取用户信息*/ 35 | @Value("${wxopen.user_info_url}") 36 | public String userInfoUrl; 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/constant/CommonConstants.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.constant; 2 | 3 | /** 4 | * @Author: 小莫 5 | * @Date: 2019-04-09 11:34 6 | * @Description TODO 通用常量 7 | */ 8 | public interface CommonConstants { 9 | /*表示等待处理*/ 10 | String SOURCE_STATE_WAIT = "WAITTING"; 11 | /*表示已经处理完成*/ 12 | String SOURCE_STATE_PROCESS = "PROCESSED"; 13 | /*JWT 主题*/ 14 | String JWT_SUBJECT = "crawler"; 15 | /*过期时间,设置为一周*/ 16 | long JWT_TOKEN_EXPIRE_TIME = 1000*60*60*24*7; 17 | /*秘钥*/ 18 | String JWT_APPSECRET = "mzj584wanlhy"; 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/controller/CrawlerController.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.controller; 2 | 3 | import com.xmlvhy.crawler.entity.ResponseResult; 4 | import com.xmlvhy.crawler.service.CrawlerService; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Controller; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.ResponseBody; 9 | 10 | /** 11 | * @ClassName CrawlerController 12 | * @Description TODO: 爬虫接口 13 | * @Author 小莫 14 | * @Date 2019/04/09 11:22 15 | * @Version 1.0 16 | **/ 17 | @Controller 18 | @RequestMapping("/api/v1") 19 | public class CrawlerController { 20 | 21 | @Autowired 22 | private CrawlerService crawlerService; 23 | 24 | @RequestMapping("crawlerSource") 25 | @ResponseBody 26 | public ResponseResult crawlerSource() { 27 | crawlerService.crawlRunner(); 28 | return ResponseResult.success(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/controller/CrawlerDataManagerController.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.controller; 2 | 3 | import com.github.pagehelper.Page; 4 | import com.xmlvhy.crawler.entity.Content; 5 | import com.xmlvhy.crawler.entity.Customer; 6 | import com.xmlvhy.crawler.entity.LayUiResponse; 7 | import com.xmlvhy.crawler.entity.ResponseResult; 8 | import com.xmlvhy.crawler.service.ContentService; 9 | import com.xmlvhy.crawler.service.CustomerService; 10 | import com.xmlvhy.crawler.utils.CommonUtil; 11 | import com.xmlvhy.crawler.utils.JwtUtils; 12 | import io.jsonwebtoken.Claims; 13 | import lombok.extern.slf4j.Slf4j; 14 | import org.springframework.beans.factory.annotation.Autowired; 15 | import org.springframework.stereotype.Controller; 16 | import org.springframework.ui.Model; 17 | import org.springframework.web.bind.annotation.PathVariable; 18 | import org.springframework.web.bind.annotation.RequestMapping; 19 | import org.springframework.web.bind.annotation.RequestParam; 20 | import org.springframework.web.bind.annotation.ResponseBody; 21 | import org.springframework.web.servlet.ModelAndView; 22 | 23 | import java.text.ParseException; 24 | import java.util.HashMap; 25 | import java.util.List; 26 | import java.util.Map; 27 | 28 | /** 29 | * @ClassName CrawlerDataManagerController 30 | * @Description TODO 数据管理后台 31 | * @Author 小莫 32 | * @Date 2019/04/09 21:24 33 | * @Version 1.0 34 | **/ 35 | @Controller 36 | @Slf4j 37 | @RequestMapping("/manage") 38 | public class CrawlerDataManagerController { 39 | 40 | @Autowired 41 | private ContentService contentService; 42 | @Autowired 43 | private CustomerService customerService; 44 | 45 | @RequestMapping("/center") 46 | public String index(String token, Model model){ 47 | Claims claims = JwtUtils.checkJWT(token); 48 | Integer customerId = (Integer) claims.get("id"); 49 | Customer customer = customerService.getCustomerById(customerId); 50 | customer.setPassword(null); 51 | model.addAttribute("customer",customer); 52 | return "manage_center"; 53 | } 54 | 55 | /** 56 | *功能描述: 展示所有爬取的数据 57 | * @Author 小莫 58 | * @Date 22:28 2019/04/09 59 | * @Param [] 60 | * @return java.util.Map 61 | */ 62 | @RequestMapping("list") 63 | @ResponseBody 64 | public Map getContentList(){ 65 | List> contentList = contentService.getAllContents(); 66 | Map result = new HashMap(); 67 | if (contentList.size() > 0) { 68 | //layui对前台返回的数据是有格式要求的 69 | result.put("code", 0); 70 | result.put("msg", ""); 71 | result.put("count", contentList.size()); 72 | result.put("data",contentList); 73 | } 74 | return result; 75 | } 76 | 77 | /** 78 | *功能描述: 分页获取数据 79 | * @Author 小莫 80 | * @Date 12:32 2019/04/10 81 | * @Param [page, limit] 82 | * @return java.util.Map 83 | */ 84 | @RequestMapping("list_by_page") 85 | @ResponseBody 86 | public Map findContentsByPage(@RequestParam(name = "page",defaultValue = "1") Integer page, 87 | @RequestParam(name = "limit",defaultValue = "10") Integer limit){ 88 | Page> pageList = contentService.getAllContentsByPage(page,limit); 89 | Map result = new HashMap<>(); 90 | result.put("code",0); 91 | result.put("msg",""); 92 | result.put("count",pageList.getTotal()); //Total 代表是不分页的情况下记录总数是多少 93 | result.put("data",pageList.getResult());//result属性包含了当前页的数据 94 | return result; 95 | } 96 | 97 | /** 98 | *功能描述: 根据条件获取分页数据 99 | * @Author 小莫 100 | * @Date 12:58 2019/04/10 101 | * @Param [page, limit, channelId, contentType, keyword] 102 | * @return com.xmlvhy.crawler.entity.LayUiResponse 103 | */ 104 | @RequestMapping("list_by_params") 105 | @ResponseBody 106 | public LayUiResponse findContentByPageAndParams(@RequestParam(name = "page",defaultValue = "1") Integer page, 107 | @RequestParam(name = "limit",defaultValue = "10") Integer limit, 108 | Integer channelId, String contentType, String keyword){ 109 | 110 | Page> mapPage = contentService.getAllContentsByPageAndParams(page, limit, channelId,contentType,keyword); 111 | return LayUiResponse.result(mapPage.getTotal(),mapPage.getResult()); 112 | } 113 | 114 | /** 115 | *功能描述: 删除一条内容 116 | * @Author 小莫 117 | * @Date 14:47 2019/04/10 118 | * @Param [contentId] 119 | * @return com.xmlvhy.crawler.entity.ResponseResult 120 | */ 121 | @RequestMapping("delete") 122 | @ResponseBody 123 | public ResponseResult deleteContent(Long contentId){ 124 | if (contentService.removeContent(contentId)) { 125 | return ResponseResult.success("该条内容已被删除"); 126 | } 127 | return ResponseResult.fail("内容删除失败"); 128 | } 129 | 130 | /** 131 | *功能描述: 预览接口 132 | * @Author 小莫 133 | * @Date 15:21 2019/04/10 134 | * @Param [contentId] 135 | * @return org.springframework.web.servlet.ModelAndView 136 | */ 137 | @RequestMapping("/preview/{contentId}.html") 138 | public ModelAndView preview(@PathVariable(name = "contentId") Long contentId){ 139 | Content ret = contentService.findContentByContentId(contentId); 140 | if (ret == null) { 141 | log.warn("内容不存在"); 142 | return null; 143 | } 144 | Map previewData = contentService.getPreviewData(contentId); 145 | Content content = (Content) previewData.get("content"); 146 | String time = null; 147 | try { 148 | time = CommonUtil.convertTimeToFormat(content.getPasstime()); 149 | } catch (ParseException e) { 150 | log.error("时间转化失败"); 151 | } 152 | ModelAndView mv = new ModelAndView("preview"); 153 | mv.addAllObjects(previewData); 154 | mv.addObject("time",time); 155 | return mv; 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/controller/LoginController.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.controller; 2 | 3 | import com.xmlvhy.crawler.entity.Customer; 4 | import com.xmlvhy.crawler.entity.ResponseResult; 5 | import com.xmlvhy.crawler.service.CustomerService; 6 | import com.xmlvhy.crawler.utils.CommonUtil; 7 | import com.xmlvhy.crawler.utils.JwtUtils; 8 | import com.xmlvhy.crawler.vo.CustomerVo; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Controller; 11 | import org.springframework.web.bind.annotation.RequestMapping; 12 | import org.springframework.web.bind.annotation.RequestMethod; 13 | import org.springframework.web.bind.annotation.ResponseBody; 14 | 15 | import javax.servlet.http.HttpSession; 16 | import java.util.HashMap; 17 | import java.util.Map; 18 | 19 | /** 20 | * @ClassName LoginController 21 | * @Description TODO 22 | * @Author 小莫 23 | * @Date 2019/04/12 15:20 24 | * @Version 1.0 25 | **/ 26 | @Controller 27 | public class LoginController { 28 | 29 | @Autowired 30 | private CustomerService customerService; 31 | 32 | /** 33 | *功能描述: 登录页面 34 | * @Author 小莫 35 | * @Date 20:45 2019/04/12 36 | * @Param [] 37 | * @return java.lang.String 38 | */ 39 | @RequestMapping("/") 40 | public String index(){ 41 | return "login"; 42 | } 43 | 44 | /** 45 | *功能描述: 确认登录 46 | * @Author 小莫 47 | * @Date 20:45 2019/04/12 48 | * @Param [username, password, code, session] 49 | * @return com.xmlvhy.crawler.entity.ResponseResult 50 | */ 51 | @RequestMapping("login") 52 | @ResponseBody 53 | public ResponseResult login(String username, String password, 54 | String code, HttpSession session){ 55 | 56 | String RandCode = (String) session.getAttribute("code"); 57 | 58 | //校验验证码 59 | if (!RandCode.equalsIgnoreCase(code)) { 60 | return ResponseResult.fail("验证码不正确"); 61 | } 62 | 63 | Customer customer = customerService.checkPasswordAndLoginName(username, password); 64 | Map token = new HashMap(); 65 | if (customer != null) { 66 | String ret = JwtUtils.geneJsonWebToken(customer); 67 | token.put("token",ret); 68 | session.setAttribute("token",ret); 69 | return ResponseResult.success("登录成功!",token); 70 | } 71 | return ResponseResult.fail("用户名或密码不正确"); 72 | } 73 | 74 | /** 75 | *功能描述: 退出登录 76 | * @Author 小莫 77 | * @Date 20:44 2019/04/12 78 | * @Param [session] 79 | * @return java.lang.String 80 | */ 81 | @RequestMapping("logout") 82 | public String logout(HttpSession session){ 83 | session.invalidate(); 84 | return "redirect:/"; 85 | } 86 | 87 | @RequestMapping(value = "register",method = RequestMethod.GET) 88 | public String register(){ 89 | return "register"; 90 | } 91 | 92 | /** 93 | *功能描述: 注册 94 | * @Author 小莫 95 | * @Date 22:00 2019/04/12 96 | * @Param [customerVo] 97 | * @return com.xmlvhy.crawler.entity.ResponseResult 98 | */ 99 | @RequestMapping(value = "register",method = RequestMethod.POST) 100 | @ResponseBody 101 | public ResponseResult register(CustomerVo customerVo){ 102 | //检查loginName 是否存在 103 | String loginName = customerVo.getLoginName(); 104 | Customer customer = customerService.getCustomerByLoginName(loginName); 105 | if (customer != null) { 106 | return ResponseResult.fail("该用户名已存在!"); 107 | } 108 | //加密密码 109 | String password = CommonUtil.MD5(customerVo.getPassword()); 110 | customerVo.setPassword(password); 111 | if (customerService.saveCustomer(customerVo)) { 112 | return ResponseResult.success("恭喜您,注册成功!"); 113 | } 114 | return ResponseResult.fail("注册失败"); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/controller/QQLoginController.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.controller; 2 | 3 | import com.xmlvhy.crawler.config.QQConfig; 4 | import com.xmlvhy.crawler.entity.Customer; 5 | import com.xmlvhy.crawler.entity.ResponseResult; 6 | import com.xmlvhy.crawler.service.CustomerService; 7 | import com.xmlvhy.crawler.utils.JwtUtils; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Controller; 11 | import org.springframework.web.bind.annotation.RequestMapping; 12 | import org.springframework.web.bind.annotation.RequestParam; 13 | import org.springframework.web.bind.annotation.ResponseBody; 14 | 15 | import javax.servlet.http.HttpServletResponse; 16 | import javax.servlet.http.HttpSession; 17 | import java.io.UnsupportedEncodingException; 18 | import java.net.URLEncoder; 19 | import java.util.HashMap; 20 | import java.util.Map; 21 | 22 | /** 23 | * @ClassName QQLoginController 24 | * @Description TODO QQ授权登录控制器 25 | * @Author 小莫 26 | * @Date 2019/04/19 13:15 27 | * @Version 1.0 28 | **/ 29 | @Controller 30 | @RequestMapping("/qq") 31 | @Slf4j 32 | public class QQLoginController { 33 | 34 | @Autowired 35 | private QQConfig qqConfig; 36 | 37 | @Autowired 38 | private CustomerService customerService; 39 | 40 | /** 41 | *功能描述: 进入qq授权登录页面 42 | * @Author 小莫 43 | * @Date 18:29 2019/04/19 44 | * @Param [state] 45 | * @return com.xmlvhy.crawler.entity.ResponseResult 46 | */ 47 | @RequestMapping("oauth") 48 | @ResponseBody 49 | public ResponseResult oauthUrl(@RequestParam(value = "state",required = true) String state) throws UnsupportedEncodingException { 50 | String access_page = URLEncoder.encode(state,"utf-8"); 51 | String callBackUrl = qqConfig.getRedirectUrl(); 52 | 53 | String oauthUrl = String.format(qqConfig.getOauthUrl(), qqConfig.getAppId(), callBackUrl, access_page); 54 | 55 | Map ret = new HashMap<>(); 56 | ret.put("oauthUrl",oauthUrl); 57 | return ResponseResult.success(ret); 58 | } 59 | 60 | /** 61 | *功能描述: qq回调 62 | * @Author 小莫 63 | * @Date 18:29 2019/04/19 64 | * @Param [code, state, session, response] 65 | * @return java.lang.String 66 | */ 67 | @RequestMapping("login") 68 | public String callBack(@RequestParam("code") String code, 69 | @RequestParam("state") String state, 70 | HttpSession session, HttpServletResponse response){ 71 | log.info("code: {},state :{}",code,state); 72 | Customer customer = customerService.saveQQCustomer(code); 73 | if (customer != null) { 74 | String token = JwtUtils.geneJsonWebToken(customer); 75 | session.setAttribute("token",token); 76 | //String redirectUrl = state + "?token=" + token; 77 | //log.info("QQ 授权登录成功进入:{}",redirectUrl); 78 | //try { 79 | // response.sendRedirect(redirectUrl); 80 | //} catch (IOException e) { 81 | // log.error("重定向失败,原因: {}",e.getMessage()); 82 | //} 83 | //转到后台页面 84 | return "redirect:/manage/center"+"?token="+token; 85 | } 86 | //转到登录页面 87 | return "redirect:/"; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/controller/TestController.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.controller; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | /** 8 | * @ClassName TestController 9 | * @Description TODO 10 | * @Author 小莫 11 | * @Date 2019/04/08 22:33 12 | * @Version 1.0 13 | **/ 14 | @RestController 15 | @RequestMapping("/api/v1") 16 | @Slf4j 17 | public class TestController { 18 | 19 | @RequestMapping("test") 20 | public void crawlerTest(){ 21 | /*以下四个连接爬取的数据已经被加密,这里使用之前的api接口*/ 22 | //推荐 23 | //String url = "http://s.budejie.com/v2/topic/list/1/0-0/budejie-android-8.0.5/0-25.json"; 24 | ////视频 25 | //String video_url = "http://s.budejie.com/v2/topic/list/41/0-0/budejie-android-8.0.5/0-25.json"; 26 | ////图片 27 | //String image_url = "http://s.budejie.com/v2/topic/list/10/0-0/budejie-android-8.0.5/0-25.json"; 28 | ////笑话 29 | //String joke_url = "http://s.budejie.com/v2/topic/list/29/0-0/budejie-android-8.0.5/0-25.json"; 30 | 31 | // URL模板 32 | String[] templates = new String[]{ 33 | "http://c.api.budejie.com/topic/list/jingxuan/1/budejie-android-6.9.4/0-20.json?market=xiaomi&ver=6.9.4&visiting=&os=6.0&appname=baisibudejie&client=android&udid=864141036474044&mac=02%3A00%3A00%3A00%3A00%3A00" 34 | , "http://c.api.budejie.com/topic/list/jingxuan/41/budejie-android-6.9.4/0-20.json?market=xiaomi&ver=6.9.4&visiting=&os=6.0&appname=baisibudejie&client=android&udid=864141036474044&mac=02%3A00%3A00%3A00%3A00%3A00" 35 | , "http://c.api.budejie.com/topic/list/jingxuan/10/budejie-android-6.9.4/0-20.json?market=xiaomi&ver=6.9.4&visiting=&os=6.0&appname=baisibudejie&client=android&udid=864141036474044&mac=02%3A00%3A00%3A00%3A00%3A00" 36 | , "http://c.api.budejie.com/topic/list/jingxuan/29/budejie-android-6.9.4/0-20.json?market=xiaomi&ver=6.9.4&visiting=&os=6.0&appname=baisibudejie&client=android&udid=864141036474044&mac=02%3A00%3A00%3A00%3A00%3A00" 37 | , "http://s.budejie.com/topic/list/remen/1/budejie-android-6.9.4/0-20.json?market=xiaomi&ver=6.9.4&visiting=&os=6.0&appname=baisibudejie&client=android&udid=864141036474044&mac=02%3A00%3A00%3A00%3A00%3A00" 38 | }; 39 | // for(int i = 0; i< templates.length;i++){ 40 | // String url = templates[i]; 41 | // //1.创建okHttp 对象 42 | // OkHttpClient client = new OkHttpClient(); 43 | // //2.构建请求,设置要访问的url 44 | // Request.Builder builder = new Request.Builder().url(url); 45 | // //设置请求头 46 | // builder.addHeader("User-Agent" , "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36"); 47 | // //创建设置好的请求对象 48 | // Request request = builder.build(); 49 | // String result = null; 50 | // 51 | // try { 52 | // log.info("正在爬取第 {} 个模块的数据",i+1); 53 | // //3.发送请求 54 | // Response response = client.newCall(request).execute(); 55 | // result = response.body().string(); 56 | // log.info("第{}个模块,URL:{} ,爬取的数据:{}",i+1,url,result); 57 | // } catch (IOException e) { 58 | // e.printStackTrace(); 59 | // log.info("第 {} 个模块数据爬取失败,URL: {} ,原因:链接超时",i+1,url); 60 | // continue; 61 | // } 62 | // } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/controller/VerifyCodeController.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.controller; 2 | 3 | import com.xmlvhy.crawler.utils.CodeUtil; 4 | import org.springframework.stereotype.Controller; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | 7 | import javax.imageio.ImageIO; 8 | import javax.servlet.http.HttpServletRequest; 9 | import javax.servlet.http.HttpServletResponse; 10 | import javax.servlet.http.HttpSession; 11 | import java.awt.image.RenderedImage; 12 | import java.io.IOException; 13 | import java.util.Map; 14 | 15 | /** 16 | * Author: 小莫 17 | * Date: 2019-03-12 9:34 18 | * Description: 生成验证接口 19 | */ 20 | @Controller 21 | @RequestMapping("/code") 22 | public class VerifyCodeController { 23 | 24 | /** 25 | *功能描述: 获取验证码图片 26 | * @Author 小莫 27 | * @Date 9:53 2019/03/12 28 | * @Param [request, response] 29 | * @return void 30 | */ 31 | @RequestMapping("getCodeImage") 32 | public void getCodeImage(HttpServletRequest request, HttpServletResponse response){ 33 | 34 | Map map = CodeUtil.generateCodeAndPic(); 35 | 36 | //创建一个session,将生成的随机验证码放到session中 37 | HttpSession session = request.getSession(); 38 | session.setAttribute("code",map.get("code").toString()); 39 | 40 | // 禁止图像缓存。 41 | response.setHeader("Pragma", "no-cache"); 42 | response.setHeader("Cache-Control", "no-cache"); 43 | response.setDateHeader("Expires", -1); 44 | response.setContentType("image/jpeg"); 45 | 46 | try { 47 | //将生成的验证图标写入到输出流中,显示验证码 48 | ImageIO.write((RenderedImage) map.get("codePic"),"jpeg",response.getOutputStream()); 49 | } catch (IOException e) { 50 | e.printStackTrace(); 51 | } 52 | } 53 | //@RequestMapping("checkRandCode") 54 | //@ResponseBody 55 | //public Map checkRandCode(String randCode, HttpSession session){ 56 | // Map map = new HashMap<>(); 57 | // String code = (String) session.getAttribute("code"); 58 | // //匹配验证码,不区分大小写 59 | // if (code.equalsIgnoreCase(randCode)) { 60 | // map.put("valid",true); 61 | // }else{ 62 | // map.put("valid",false); 63 | // } 64 | // return map; 65 | //} 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/controller/WeChatController.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.controller; 2 | 3 | import com.xmlvhy.crawler.config.WeChatConfig; 4 | import com.xmlvhy.crawler.entity.Customer; 5 | import com.xmlvhy.crawler.entity.ResponseResult; 6 | import com.xmlvhy.crawler.service.CustomerService; 7 | import com.xmlvhy.crawler.utils.JwtUtils; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Controller; 11 | import org.springframework.web.bind.annotation.RequestMapping; 12 | import org.springframework.web.bind.annotation.RequestParam; 13 | import org.springframework.web.bind.annotation.ResponseBody; 14 | 15 | import javax.servlet.http.HttpServletResponse; 16 | import javax.servlet.http.HttpSession; 17 | import java.io.IOException; 18 | import java.io.UnsupportedEncodingException; 19 | import java.net.URLEncoder; 20 | import java.util.HashMap; 21 | import java.util.Map; 22 | 23 | /** 24 | * @ClassName WeChatController 25 | * @Description TODO 26 | * @Author 小莫 27 | * @Date 2019/04/13 19:53 28 | * @Version 1.0 29 | **/ 30 | @Controller 31 | @RequestMapping("/weChat") 32 | @Slf4j 33 | public class WeChatController { 34 | 35 | @Autowired 36 | private CustomerService customerService; 37 | 38 | @Autowired 39 | private WeChatConfig weChatConfig; 40 | 41 | /** 42 | *功能描述: 首先调出微信登录二维码扫一扫页面 43 | * @Author 小莫 44 | * @Date 20:07 2019/04/13 45 | * @Param [accessPage] 46 | * @return com.xmlvhy.crawler.entity.ResponseResult 47 | */ 48 | @RequestMapping("login_url") 49 | @ResponseBody 50 | public ResponseResult getWeChatLoginQRCodeUrl(@RequestParam(value = "access_page", required = true) String accessPage) { 51 | //获取开放平台重定向地址 52 | String redirectUrl = weChatConfig.getRedirectUrl(); 53 | Map ret = new HashMap<>(); 54 | try { 55 | String callBackUrl = URLEncoder.encode(redirectUrl, "GBK"); 56 | //TODO:可以直接格式化替换 对应%s的参数 57 | String qrodeUrl = String.format(weChatConfig.getOpenQRCodeUrl(), weChatConfig.getAppId(), callBackUrl, accessPage); 58 | ret.put("qrCodeUrl",qrodeUrl); 59 | return ResponseResult.success(ret); 60 | } catch (UnsupportedEncodingException e) { 61 | log.info("回调地址编码失败:{}", e.getMessage()); 62 | return ResponseResult.fail("调出微信扫码登录url失败,请重新尝试"); 63 | } 64 | } 65 | 66 | @RequestMapping("callback") 67 | public void weChatCallBack(@RequestParam(value = "code",required = true) String code, 68 | String state, HttpServletResponse response, 69 | HttpSession session){ 70 | log.info("code: {} , state: {}",code,state); 71 | Customer customer = customerService.saveWeChatCustomer(code); 72 | if (customer != null) { 73 | //生成jwt 74 | String token = JwtUtils.geneJsonWebToken(customer); 75 | session.setAttribute("token",token); 76 | 77 | //state 参数表示当前授权登录后要登入的网页url,需要拼接 http:// 这样才不会页面内跳转 78 | String redirectUrl = state + "?token="+token; 79 | log.info("redirectUrl: {}",redirectUrl); 80 | try { 81 | response.sendRedirect(redirectUrl); 82 | } catch (IOException e) { 83 | log.info("重定向失败,原因:{}",e.getMessage()); 84 | } 85 | } 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/dao/ChannelMapper.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.dao; 2 | 3 | import com.xmlvhy.crawler.entity.Channel; 4 | 5 | public interface ChannelMapper { 6 | int deleteByPrimaryKey(Long channelId); 7 | 8 | int insert(Channel record); 9 | 10 | int insertSelective(Channel record); 11 | 12 | Channel selectByPrimaryKey(Long channelId); 13 | 14 | int updateByPrimaryKeySelective(Channel record); 15 | 16 | int updateByPrimaryKey(Channel record); 17 | } -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/dao/CommentMapper.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.dao; 2 | 3 | import com.xmlvhy.crawler.entity.Comment; 4 | 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | public interface CommentMapper { 9 | int deleteByPrimaryKey(Long commentId); 10 | 11 | int insert(Comment record); 12 | 13 | int insertSelective(Comment record); 14 | 15 | Comment selectByPrimaryKey(Long commentId); 16 | 17 | int updateByPrimaryKeySelective(Comment record); 18 | 19 | int updateByPrimaryKey(Comment record); 20 | 21 | List> selectByContentId(Long contentId); 22 | } -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/dao/ContentMapper.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.dao; 2 | 3 | import com.xmlvhy.crawler.entity.Content; 4 | 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | public interface ContentMapper { 9 | int deleteByPrimaryKey(Long contentId); 10 | 11 | int insert(Content record); 12 | 13 | int insertSelective(Content record); 14 | 15 | Content selectByPrimaryKey(Long contentId); 16 | 17 | int updateByPrimaryKeySelective(Content record); 18 | 19 | int updateByPrimaryKey(Content record); 20 | 21 | List> selectAll(); 22 | 23 | List> selectByParams(Map params); 24 | } -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/dao/CustomerMapper.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.dao; 2 | 3 | import com.xmlvhy.crawler.entity.Customer; 4 | import org.apache.ibatis.annotations.Param; 5 | 6 | public interface CustomerMapper { 7 | int deleteByPrimaryKey(Integer id); 8 | 9 | int insert(Customer record); 10 | 11 | int insertSelective(Customer record); 12 | 13 | Customer selectByPrimaryKey(Integer id); 14 | 15 | int updateByPrimaryKeySelective(Customer record); 16 | 17 | int updateByPrimaryKey(Customer record); 18 | 19 | Customer selectByPwdAndLoginName(@Param("loginName") String username, 20 | @Param("password") String password); 21 | 22 | Customer selectCustomerByLoginName(String loginName); 23 | 24 | Customer selectCustomerByOpenId(String openid); 25 | } -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/dao/ForumMapper.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.dao; 2 | 3 | import com.xmlvhy.crawler.entity.Forum; 4 | 5 | public interface ForumMapper { 6 | int deleteByPrimaryKey(Long forumId); 7 | 8 | int insert(Forum record); 9 | 10 | int insertSelective(Forum record); 11 | 12 | Forum selectByPrimaryKey(Long forumId); 13 | 14 | int updateByPrimaryKeySelective(Forum record); 15 | 16 | int updateByPrimaryKey(Forum record); 17 | } -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/dao/ImageMapper.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.dao; 2 | 3 | import com.xmlvhy.crawler.entity.Image; 4 | 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | public interface ImageMapper { 9 | int deleteByPrimaryKey(Long imageId); 10 | 11 | int insert(Image record); 12 | 13 | int insertSelective(Image record); 14 | 15 | Image selectByPrimaryKey(Long imageId); 16 | 17 | int updateByPrimaryKeySelective(Image record); 18 | 19 | int updateByPrimaryKey(Image record); 20 | 21 | List> selectByContentId(Long contentId); 22 | } -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/dao/SourceDao.java.bak: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.dao; 2 | 3 | import com.xmlvhy.crawler.entity.Source; 4 | 5 | /** 6 | * @Author: 小莫 7 | * @Date: 2019-04-09 15:43 8 | * @Description TODO: 原始数据 dao 层 9 | */ 10 | public interface SourceDao { 11 | 12 | int saveSource(Source source); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/dao/SourceMapper.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.dao; 2 | 3 | import com.xmlvhy.crawler.entity.Source; 4 | 5 | import java.util.List; 6 | 7 | public interface SourceMapper { 8 | int deleteByPrimaryKey(Long sourceId); 9 | 10 | int insert(Source record); 11 | 12 | int insertSelective(Source record); 13 | 14 | Source selectByPrimaryKey(Long sourceId); 15 | 16 | int updateByPrimaryKeySelective(Source record); 17 | 18 | int updateByPrimaryKey(Source record); 19 | 20 | List findAllByState(String state); 21 | } -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/dao/UserMapper.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.dao; 2 | 3 | import com.xmlvhy.crawler.entity.User; 4 | 5 | public interface UserMapper { 6 | int deleteByPrimaryKey(Long uid); 7 | 8 | int insert(User record); 9 | 10 | int insertSelective(User record); 11 | 12 | User selectByPrimaryKey(Long uid); 13 | 14 | int updateByPrimaryKeySelective(User record); 15 | 16 | int updateByPrimaryKey(User record); 17 | } -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/dao/VideoMapper.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.dao; 2 | 3 | import com.xmlvhy.crawler.entity.Video; 4 | 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | public interface VideoMapper { 9 | int deleteByPrimaryKey(Long videoId); 10 | 11 | int insert(Video record); 12 | 13 | int insertSelective(Video record); 14 | 15 | Video selectByPrimaryKey(Long videoId); 16 | 17 | int updateByPrimaryKeySelective(Video record); 18 | 19 | int updateByPrimaryKey(Video record); 20 | 21 | List> selectByContentId(Long contentId); 22 | } -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/entity/Channel.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.entity; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | @Data 8 | @NoArgsConstructor 9 | @AllArgsConstructor 10 | public class Channel { 11 | /*频道id*/ 12 | private Long channelId; 13 | /*频道名称*/ 14 | private String channelName; 15 | /*频道顺序*/ 16 | private Integer sortNum; 17 | } -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/entity/Comment.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.entity; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | @Data 8 | @NoArgsConstructor 9 | @AllArgsConstructor 10 | public class Comment { 11 | /*评论ID*/ 12 | private Long commentId; 13 | /*评论内容*/ 14 | private String commentText; 15 | /*评论用户的id*/ 16 | private Long uid; 17 | /*过审时间*/ 18 | private String passtime; 19 | /*内容Id*/ 20 | private Long contentId; 21 | } -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/entity/Content.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.entity; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.Date; 8 | 9 | @Data 10 | @NoArgsConstructor 11 | @AllArgsConstructor 12 | public class Content { 13 | /*内容id*/ 14 | private Long contentId; 15 | /*频道id*/ 16 | private Long channelId; 17 | /*圈子id*/ 18 | private Long forumId; 19 | /*用户id*/ 20 | private Long uid; 21 | /*状态 4 过审*/ 22 | private Integer status; 23 | /*评论数量*/ 24 | private Integer commentCount; 25 | /*收藏数量*/ 26 | private Integer bookmarkCount; 27 | /*标题或者正文*/ 28 | private String contentText; 29 | /*点赞数量*/ 30 | private Integer likeCount; 31 | /*踩的数量*/ 32 | private Integer hateCount; 33 | /*分享url*/ 34 | private String shareUrl; 35 | /*分享数量*/ 36 | private Integer shareCount; 37 | /*发布时间*/ 38 | private String passtime; 39 | /*内容类型 text/image/video/gif*/ 40 | private String contentType; 41 | /*数据源id*/ 42 | private Long sourceId; 43 | /*创建时间*/ 44 | private Date createTime; 45 | } -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/entity/Customer.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.entity; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.Date; 8 | 9 | @Data 10 | @AllArgsConstructor 11 | @NoArgsConstructor 12 | public class Customer { 13 | 14 | /*主键*/ 15 | private Integer id; 16 | /*用户姓名*/ 17 | private String name; 18 | /*用户密码*/ 19 | private String password; 20 | /*用户微信uid*/ 21 | private String uid; 22 | /*用户昵称*/ 23 | private String nickname; 24 | /*用户头像*/ 25 | private String header = "https://www.xmlvhy.com/images/user.png"; 26 | /*用户登账户名*/ 27 | private String loginName; 28 | /*用户签名*/ 29 | private String sign; 30 | /*用户性别*/ 31 | private String sex; 32 | /*用户创建时间*/ 33 | private Date createTime; 34 | 35 | } -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/entity/Forum.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.entity; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | @Data 8 | @NoArgsConstructor 9 | @AllArgsConstructor 10 | public class Forum { 11 | /*圈子id*/ 12 | private Long forumId; 13 | /*发帖数量*/ 14 | private Integer postCount; 15 | /*Logo Url*/ 16 | private String logo; 17 | /*频道顺序*/ 18 | private Integer forumSort; 19 | /*圈子状态*/ 20 | private Integer forumStatus; 21 | /*圈子简介*/ 22 | private String info; 23 | /*圈子名称*/ 24 | private String name; 25 | /*圈子参与的用户数量*/ 26 | private Integer userCount; 27 | } -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/entity/Image.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.entity; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | @Data 8 | @NoArgsConstructor 9 | @AllArgsConstructor 10 | public class Image { 11 | /*图片id,自增*/ 12 | private Long imageId; 13 | /*经过压缩后的大图(600P)url*/ 14 | private String bigUrl; 15 | /*带水印大图url*/ 16 | private String watermarkerUrl; 17 | /*原图高度*/ 18 | private Integer rawHeight; 19 | /*原图宽度*/ 20 | private Integer rawWidth; 21 | /*缩略图url*/ 22 | private String thumbUrl; 23 | /*内容编号id*/ 24 | private Long contentId; 25 | } -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/entity/LayUiResponse.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.entity; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * @ClassName LayUiResponse 9 | * @Description TODO 10 | * @Author 小莫 11 | * @Date 2019/04/10 12:54 12 | * @Version 1.0 13 | **/ 14 | @Data 15 | @AllArgsConstructor 16 | @NoArgsConstructor 17 | public class LayUiResponse { 18 | private Integer code; 19 | private String msg; 20 | private Long count; 21 | private Object data; 22 | 23 | /** 24 | *功能描述: 响应layui form 数据封装 25 | * @Author 小莫 26 | * @Date 12:56 2019/04/10 27 | * @Param [count, data] 28 | * @return com.xmlvhy.crawler.entity.LayUiResponse 29 | */ 30 | public static LayUiResponse result(Long count,Object data){ 31 | return new LayUiResponse(0,"",count,data); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/entity/ResponseResult.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.entity; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * @ClassName ResponseResult 9 | * @Description TODO 响应数据封装类 10 | * @Author 小莫 11 | * @Date 2019/04/09 11:25 12 | * @Version 1.0 13 | **/ 14 | @Data 15 | @AllArgsConstructor 16 | @NoArgsConstructor 17 | public class ResponseResult { 18 | 19 | /*响应码 0表示成功,1表示失败*/ 20 | private Integer code; 21 | /*响应消息*/ 22 | private String msg; 23 | /*响应数据*/ 24 | private Object data; 25 | 26 | /** 27 | *功能描述: 成功,未带返回数据 28 | * @Author 小莫 29 | * @Date 11:38 2019/04/09 30 | * @Param [] 31 | * @return com.xmlvhy.crawler.entity.ResponseResult 32 | */ 33 | public static ResponseResult success(){ 34 | return new ResponseResult(0,"success",null); 35 | } 36 | 37 | /** 38 | *功能描述: 成功带消息 39 | * @Author 小莫 40 | * @Date 11:40 2019/04/09 41 | * @Param [msg] 42 | * @return com.xmlvhy.crawler.entity.ResponseResult 43 | */ 44 | public static ResponseResult success(String msg){ 45 | return new ResponseResult(0,msg,null); 46 | } 47 | 48 | /** 49 | *功能描述: 成功带消息和数据 50 | * @Author 小莫 51 | * @Date 11:40 2019/04/09 52 | * @Param [msg, data] 53 | * @return com.xmlvhy.crawler.entity.ResponseResult 54 | */ 55 | public static ResponseResult success(String msg,Object data){ 56 | return new ResponseResult(0,msg,data); 57 | } 58 | 59 | /** 60 | *功能描述: 成功只带数据 61 | * @Author 小莫 62 | * @Date 11:41 2019/04/09 63 | * @Param [data] 64 | * @return com.xmlvhy.crawler.entity.ResponseResult 65 | */ 66 | public static ResponseResult success(Object data){ 67 | return new ResponseResult(0,"success",data); 68 | } 69 | 70 | /** 71 | *功能描述: 失败不带消息 72 | * @Author 小莫 73 | * @Date 11:43 2019/04/09 74 | * @Param [] 75 | * @return com.xmlvhy.crawler.entity.ResponseResult 76 | */ 77 | public static ResponseResult fail(){ 78 | return new ResponseResult(1,"fail",null); 79 | } 80 | 81 | /** 82 | *功能描述: 失败带消息 83 | * @Author 小莫 84 | * @Date 11:42 2019/04/09 85 | * @Param [msg] 86 | * @return com.xmlvhy.crawler.entity.ResponseResult 87 | */ 88 | public static ResponseResult fail(String msg){ 89 | return new ResponseResult(1,msg,null); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/entity/Source.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.entity; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.Date; 8 | 9 | @Data 10 | @NoArgsConstructor 11 | @AllArgsConstructor 12 | public class Source { 13 | /*数据源id*/ 14 | private Long sourceId; 15 | /*频道id*/ 16 | private Long channelId; 17 | /*爬取的源数据*/ 18 | private String responseText; 19 | /*创建时间*/ 20 | private Date createTime; 21 | /*url*/ 22 | private String url; 23 | /*状态 WAITTING 表示待处理状态,PROCESSED 表示已处理*/ 24 | private String state; 25 | } -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/entity/Source.java.bak: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.entity; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.Date; 8 | 9 | /** 10 | * @ClassName Source 11 | * @Description TODO: 源数据 12 | * @Author 小莫 13 | * @Date 2019/04/09 15:23 14 | * @Version 1.0 15 | **/ 16 | @Data 17 | @AllArgsConstructor 18 | @NoArgsConstructor 19 | public class Source { 20 | /*数据源id*/ 21 | private Long sourceId; 22 | /*频道id*/ 23 | private Long channelId; 24 | /*爬取的源数据*/ 25 | private String responseText; 26 | /*创建时间*/ 27 | private Date createTime; 28 | /*url*/ 29 | private String url; 30 | /*状态 WAITTING 表示待处理状态,PROCESSED 表示已处理*/ 31 | private String state; 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/entity/User.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.entity; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | @Data 8 | @AllArgsConstructor 9 | @NoArgsConstructor 10 | public class User { 11 | /*用户id*/ 12 | private Long uid; 13 | /*用户头像url*/ 14 | private String header; 15 | /*是够是vip 0否 1是*/ 16 | private Integer isVip; 17 | private Integer isV; 18 | /*房间url*/ 19 | private String roomUrl; 20 | /*房间名称*/ 21 | private String roomName; 22 | /*房间角色*/ 23 | private String roomRole; 24 | /*房间logo*/ 25 | private String roomIcon; 26 | /*用户昵称*/ 27 | private String nickname; 28 | } -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/entity/Video.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.entity; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | @Data 8 | @NoArgsConstructor 9 | @AllArgsConstructor 10 | public class Video { 11 | /*视频id 自增*/ 12 | private Long videoId; 13 | /*视频播放url*/ 14 | private String videoUrl; 15 | /*视频下载url*/ 16 | private String downloadUrl; 17 | /*视频播放宽度*/ 18 | private Integer width; 19 | /*视频播放高度*/ 20 | private Integer height; 21 | /*视频播放量*/ 22 | private Integer playfcount; 23 | /*播放时长,单位秒*/ 24 | private Integer duration; 25 | private Integer playcount; 26 | /*视频缩略图,等比例*/ 27 | private String thumb; 28 | /*视频缩略图 正方*/ 29 | private String thumbSmall; 30 | /*内容id*/ 31 | private Long contentId; 32 | } -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/exception/CrawlerException.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.exception; 2 | 3 | /** 4 | * @ClassName CrawlerException 5 | * @Description TODO 自定义异常类 6 | * @Author 小莫 7 | * @Date 2019/04/12 17:53 8 | * @Version 1.0 9 | **/ 10 | public class CrawlerException extends RuntimeException{ 11 | 12 | public CrawlerException() { 13 | super(); 14 | } 15 | 16 | public CrawlerException(String message) { 17 | super(message); 18 | } 19 | 20 | public CrawlerException(String message, Throwable cause) { 21 | super(message, cause); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/exception/CrawlerExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.exception; 2 | 3 | import org.springframework.web.bind.annotation.ControllerAdvice; 4 | import org.springframework.web.bind.annotation.ExceptionHandler; 5 | 6 | /** 7 | * @ClassName CrawlerExceptionHandler 8 | * @Description TODO 全局异常捕获类 9 | * @Author 小莫 10 | * @Date 2019/04/14 11:32 11 | * @Version 1.0 12 | **/ 13 | @ControllerAdvice 14 | public class CrawlerExceptionHandler { 15 | 16 | @ExceptionHandler(Exception.class) 17 | public String exceptionHandler(){ 18 | return "error/5xx"; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/interceptors/LoginInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.interceptors; 2 | 3 | import com.xmlvhy.crawler.utils.JwtUtils; 4 | import io.jsonwebtoken.Claims; 5 | import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; 6 | 7 | import javax.servlet.http.HttpServletRequest; 8 | import javax.servlet.http.HttpServletResponse; 9 | 10 | /** 11 | * @ClassName LoginInterceptor 12 | * @Description TODO 登录拦截器 13 | * @Author 小莫 14 | * @Date 2019/04/12 18:48 15 | * @Version 1.0 16 | **/ 17 | public class LoginInterceptor extends HandlerInterceptorAdapter { 18 | 19 | @Override 20 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 21 | //String token = request.getHeader("token"); 22 | //if (token == null) { 23 | // token = request.getParameter("token"); 24 | //} 25 | String token = (String) request.getSession().getAttribute("token"); 26 | if (token != null) { 27 | Claims claims = JwtUtils.checkJWT(token); 28 | if (claims != null) { 29 | return true; 30 | } 31 | } 32 | //用户信息不存在,则拦截,重定向到后台登陆界面 33 | response.sendRedirect("/crawler"); 34 | return false; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/interceptors/WebConfig.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.interceptors; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 5 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 6 | 7 | /** 8 | * @ClassName WebConfig 9 | * @Description TODO 10 | * @Author 小莫 11 | * @Date 2019/04/12 18:47 12 | * @Version 1.0 13 | **/ 14 | @Configuration 15 | public class WebConfig implements WebMvcConfigurer { 16 | @Override 17 | public void addInterceptors(InterceptorRegistry registry) { 18 | registry.addInterceptor(new LoginInterceptor()) 19 | .addPathPatterns("/api/v1/**") 20 | .addPathPatterns("/manage/center") 21 | .excludePathPatterns("/crawler") 22 | .excludePathPatterns("/login") 23 | .excludePathPatterns("/static/**"); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/service/ContentService.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.service; 2 | 3 | import com.github.pagehelper.Page; 4 | import com.xmlvhy.crawler.entity.Content; 5 | 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | /** 10 | * @Author: 小莫 11 | * @Date: 2019-04-10 10:13 12 | * @Description TODO 13 | */ 14 | public interface ContentService { 15 | 16 | List> getAllContents(); 17 | 18 | Page> getAllContentsByPage(Integer page,Integer pageSize); 19 | 20 | Page> getAllContentsByPageAndParams(Integer page, Integer limit,Integer channelId,String contentType,String keyword); 21 | 22 | Boolean removeContent(Long contentId); 23 | 24 | Map getPreviewData(Long contentId); 25 | 26 | Content findContentByContentId(Long contentId); 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/service/CrawlerService.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.service; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * @Author: 小莫 7 | * @Date: 2019-04-09 9:59 8 | * @Description TODO: 爬虫业务接口 9 | */ 10 | public interface CrawlerService { 11 | void crawl (String url, Map paramsMap); 12 | void crawlRunner(); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/service/CustomerService.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.service; 2 | 3 | import com.xmlvhy.crawler.entity.Customer; 4 | import com.xmlvhy.crawler.vo.CustomerVo; 5 | 6 | /** 7 | * @ClassName CustomerService 8 | * @Description TODO 9 | * @Author 小莫 10 | * @Date 2019/04/12 17:45 11 | * @Version 1.0 12 | **/ 13 | public interface CustomerService { 14 | 15 | Customer checkPasswordAndLoginName(String username,String password); 16 | 17 | Customer getCustomerById(Integer id); 18 | 19 | Boolean saveCustomer(CustomerVo customerVo); 20 | 21 | Customer getCustomerByLoginName(String loginName); 22 | 23 | Customer saveWeChatCustomer(String code); 24 | 25 | Customer saveQQCustomer(String code); 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/service/DataProcessedService.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.service; 2 | 3 | import com.xmlvhy.crawler.entity.Source; 4 | 5 | import java.util.Map; 6 | 7 | /** 8 | * @Author: 小莫 9 | * @Date: 2019-04-09 18:34 10 | * @Description TODO: 源数据处理业务层 11 | */ 12 | public interface DataProcessedService { 13 | 14 | void sourceDataEtl(); 15 | 16 | void createContent(Source source, Map contentMap); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/service/impl/CrawlerServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.service.impl; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.reflect.TypeToken; 5 | import com.xmlvhy.crawler.dao.SourceMapper; 6 | import com.xmlvhy.crawler.entity.Source; 7 | import com.xmlvhy.crawler.service.CrawlerService; 8 | import com.xmlvhy.crawler.service.DataProcessedService; 9 | import com.xmlvhy.crawler.utils.OgnlUtil; 10 | import lombok.extern.slf4j.Slf4j; 11 | import okhttp3.OkHttpClient; 12 | import okhttp3.Request; 13 | import okhttp3.Response; 14 | import org.springframework.beans.factory.annotation.Autowired; 15 | import org.springframework.beans.factory.annotation.Value; 16 | import org.springframework.stereotype.Service; 17 | 18 | import java.io.IOException; 19 | import java.text.DecimalFormat; 20 | import java.util.Date; 21 | import java.util.HashMap; 22 | import java.util.List; 23 | import java.util.Map; 24 | 25 | /** 26 | * @ClassName CrawlerServiceImpl 27 | * @Description TODO 28 | * @Author 小莫 29 | * @Date 2019/04/09 10:01 30 | * @Version 1.0 31 | **/ 32 | @Service 33 | @Slf4j 34 | public class CrawlerServiceImpl implements CrawlerService { 35 | 36 | @Value("${crawler.urls}") 37 | private String urls; 38 | 39 | @Value("${crawler.num}") 40 | private Integer num; 41 | 42 | @Value("${crawler.crawlerSum}") 43 | private Integer crawlerSum; 44 | 45 | @Autowired 46 | private SourceMapper sourceDao; 47 | 48 | @Autowired 49 | private DataProcessedService dataProcessedService; 50 | 51 | /** 52 | * 功能描述: 执行爬虫任务 53 | * 54 | * @return void 55 | * @Author 小莫 56 | * @Date 16:33 2019/04/09 57 | * @Param [url, paramsMap] 58 | * url:表示爬取的url 59 | * paramsMap表示参数集 60 | */ 61 | @Override 62 | public void crawl(String url, Map paramsMap) { 63 | //拿到对应参数 64 | Integer channelId = (Integer) paramsMap.get("channelId"); 65 | Integer count = (Integer) paramsMap.get("count"); 66 | String np = (String) paramsMap.get("np"); 67 | 68 | //每一次根据规则更新url 69 | url = url.replace("{np}", np); 70 | log.info("当前爬取的url是: {}, channelId:{}", url, channelId); 71 | 72 | //1.创建okHttp 对象 73 | OkHttpClient client = new OkHttpClient(); 74 | //2.构建请求,设置要访问的url 75 | Request.Builder builder = new Request.Builder().url(url); 76 | //设置请求头 77 | builder.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36"); 78 | //创建设置好的请求对象 79 | Request request = builder.build(); 80 | 81 | String result = null; 82 | //每个模块爬取的url设置循环爬取 num 次,超过num次未爬取到数据则失败 83 | for (int i = 0; i < num; i++) { 84 | log.info("正在执行第{}次爬取任务", i + 1); 85 | try { 86 | //3.发送请求,返回响应对象 87 | Response response = client.newCall(request).execute(); 88 | //获取返回结果 89 | result = response.body().string(); 90 | //当前爬取成功则,则跳出当前循环 91 | break; 92 | } catch (IOException e) { 93 | e.printStackTrace(); 94 | log.info("爬虫链接超时,正在准备第{}次重试,当前URL: {}", (i + 1), url); 95 | continue; 96 | } 97 | } 98 | 99 | //num 次抓取都失败,程序中断 100 | if (result == null) { 101 | log.warn("爬虫抓取失败,原因:链接超时,URL: {}", url); 102 | } 103 | 104 | Gson gson = new Gson(); 105 | Map resultMap = gson.fromJson(result, new TypeToken() { 106 | }.getType()); 107 | List> list = OgnlUtil.getListMap("list", resultMap); 108 | //获取np的内容,np是double类型,需要转化以下 109 | Double tempNp = (Double) OgnlUtil.getNumber("info.np", resultMap); 110 | //DecimalFormat代表对数字进行格式化,按要求显示 #号代表有这个数字则显示,没有则忽略 。0 ,代表没有的时候使用0占位 111 | // 123456.78 ######### -> 123456 #########.## ->123456.78 0000000000.000 -> 0000123456.780 112 | if (null != tempNp) { 113 | String strNp = new DecimalFormat("############").format(tempNp); 114 | Map tempMap = new HashMap<>(); 115 | tempMap.put("np", strNp); 116 | 117 | //保存原始数据 118 | Source source = new Source(); 119 | source.setChannelId(Long.valueOf(channelId)); 120 | source.setResponseText(result); 121 | source.setState("WAITTING"); 122 | source.setUrl(url); 123 | source.setCreateTime(new Date()); 124 | sourceDao.insert(source); 125 | log.info("数据抓取成功,NP:{},URL:{}", strNp, url); 126 | 127 | //设置爬取结束条件,根据爬取的条目总数,每个模块爬取100条数据,每次可以爬取25条 128 | count = count + list.size(); 129 | tempMap.put("count", count); 130 | tempMap.put("channelId", channelId); 131 | 132 | //只抓取最近的100条数据,每小时抓一次。大约百思每小时更新3~5条数据,所以抓最近的100条足够了 133 | log.info("当前爬取了{}条数据", count); 134 | if (count >= crawlerSum) { 135 | log.info("当前np:{} , 爬虫任务完成", strNp); 136 | return; 137 | } 138 | //利用递归进行数据抓取 139 | crawl(url, tempMap); 140 | } 141 | } 142 | 143 | /** 144 | * 功能描述: 爬虫任务执行 145 | * 146 | * @return void 147 | * @Author 小莫 148 | * @Date 16:32 2019/04/09 149 | * @Param [] 150 | */ 151 | @Override 152 | public void crawlRunner() { 153 | String[] crawlerUrls = urls.split(","); 154 | Map parmsMap = new HashMap<>(); 155 | //依次爬取推荐、视频、图片、笑话以及排行的数据 156 | for (int i = 0; i < crawlerUrls.length; i++) { 157 | log.info("开始爬取第 {}模块的数据", i + 1); 158 | String url = crawlerUrls[i]; 159 | parmsMap.put("channelId", i + 1); 160 | parmsMap.put("count", 0); 161 | parmsMap.put("np", "0"); 162 | this.crawl(url, parmsMap); 163 | } 164 | //数据爬取完成后,开始处理数据 165 | log.info("============开始处理源数据============"); 166 | Long startTime = System.currentTimeMillis(); 167 | dataProcessedService.sourceDataEtl(); 168 | Long endTime = System.currentTimeMillis(); 169 | log.info("============源数据处理完成============"); 170 | log.info("============当前处理耗时:{} 秒============", (endTime - startTime) / 1000); 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/task/CrawlerTask.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.task; 2 | 3 | import com.xmlvhy.crawler.service.CrawlerService; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.beans.factory.annotation.Value; 7 | import org.springframework.scheduling.annotation.Scheduled; 8 | import org.springframework.stereotype.Component; 9 | 10 | /** 11 | * @ClassName CrawlerTask 12 | * @Description TODO 爬虫定时任务,定时爬取数据 13 | * @Author 小莫 14 | * @Date 2019/04/10 17:17 15 | * @Version 1.0 16 | **/ 17 | @Component 18 | @Slf4j 19 | public class CrawlerTask { 20 | 21 | @Autowired 22 | private CrawlerService crawlerService; 23 | @Value("${crawler.enable}") 24 | private Integer enable; 25 | //任务执行的方法 26 | //@Scheduled 注解用于指定当前方法是一个任务调度 cron表达式指定执行的间隔 27 | //* * * * * ? 每秒执行一次 28 | //秒 分 时 日 月 星期 29 | //*代表任意时间 具体的数字代表精确值 ,用于多个值 /用于固定间隔 - 范围 ?忽略 30 | //0 * 23 * * ? 每天23点~24点之间每分钟执行一次 31 | //0 0 8-18 * ? 每天早上8点到下午六点,0份0秒准时执行一次 32 | //0 0 0 */2 * ? 0 2 4 6 ... 22 0点0分执行 33 | @Scheduled(cron = "${crawler.cron}") 34 | //@Scheduled(cron = "0 /30 * * * ?") 35 | public void crawlerTask(){ 36 | //判断是否开启爬虫任务 37 | if (enable == 0) { 38 | log.warn("爬虫任务已被禁止,如需开启请将 crawler.enable 设置为 1"); 39 | return; 40 | } 41 | //开启爬虫任务以及数据源处理 42 | crawlerService.crawlRunner(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/utils/CodeUtil.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.utils; 2 | 3 | import javax.imageio.ImageIO; 4 | import java.awt.*; 5 | import java.awt.image.BufferedImage; 6 | import java.awt.image.RenderedImage; 7 | import java.io.FileOutputStream; 8 | import java.io.OutputStream; 9 | import java.util.HashMap; 10 | import java.util.Map; 11 | import java.util.Random; 12 | 13 | /** 14 | * Author: 小莫 15 | * Date: 2019-03-12 9:38 16 | * Description: 产生验证码的工具类 17 | */ 18 | public class CodeUtil { 19 | 20 | private static int width = 90;// 定义图片的width 21 | private static int height = 20;// 定义图片的height 22 | private static int codeCount = 4;// 定义图片上显示验证码的个数 23 | private static int xx = 15; 24 | private static int fontHeight = 18; 25 | private static int codeY = 16; 26 | //验证码随机内容 27 | private static char[] codeSequence = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 28 | 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z','a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 29 | 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; 30 | 31 | /** 32 | * 生成一个map集合 33 | * code为生成的验证码 34 | * codePic为生成的验证码BufferedImage对象 35 | * @return 36 | */ 37 | public static Map generateCodeAndPic() { 38 | // 定义图像buffer 39 | BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 40 | // Graphics2D gd = buffImg.createGraphics(); 41 | // Graphics2D gd = (Graphics2D) buffImg.getGraphics(); 42 | Graphics gd = buffImg.getGraphics(); 43 | // 创建一个随机数生成器类 44 | Random random = new Random(); 45 | // 将图像填充为白色 46 | gd.setColor(Color.WHITE); 47 | gd.fillRect(0, 0, width, height); 48 | 49 | // 创建字体,字体的大小应该根据图片的高度来定。 50 | Font font = new Font("Fixedsys", Font.BOLD, fontHeight); 51 | // 设置字体。 52 | gd.setFont(font); 53 | 54 | // 画边框。 55 | gd.setColor(Color.BLACK); 56 | gd.drawRect(0, 0, width - 1, height - 1); 57 | 58 | // 随机产生40条干扰线,使图象中的认证码不易被其它程序探测到。 59 | gd.setColor(Color.BLACK); 60 | for (int i = 0; i < 15; i++) { 61 | int x = random.nextInt(width); 62 | int y = random.nextInt(height); 63 | int xl = random.nextInt(12); 64 | int yl = random.nextInt(12); 65 | gd.drawLine(x, y, x + xl, y + yl); 66 | } 67 | 68 | // randomCode用于保存随机产生的验证码,以便用户登录后进行验证。 69 | StringBuffer randomCode = new StringBuffer(); 70 | int red = 0, green = 0, blue = 0; 71 | 72 | // 随机产生codeCount数字的验证码。 73 | for (int i = 0; i < codeCount; i++) { 74 | // 得到随机产生的验证码数字。 75 | String code = String.valueOf(codeSequence[random.nextInt(62)]); 76 | // 产生随机的颜色分量来构造颜色值,这样输出的每位数字的颜色值都将不同。 77 | red = random.nextInt(255); 78 | green = random.nextInt(255); 79 | blue = random.nextInt(255); 80 | 81 | // 用随机产生的颜色将验证码绘制到图像中。 82 | gd.setColor(new Color(red, green, blue)); 83 | gd.drawString(code, (i + 1) * xx, codeY); 84 | 85 | // 将产生的四个随机数组合在一起。 86 | randomCode.append(code); 87 | } 88 | Map map = new HashMap<>(); 89 | //存放验证码 90 | map.put("code", randomCode); 91 | //存放生成的验证码BufferedImage对象 92 | map.put("codePic", buffImg); 93 | return map; 94 | } 95 | 96 | public static void main(String[] args) throws Exception { 97 | //创建文件输出流对象 98 | OutputStream out = new FileOutputStream("D://img/"+System.currentTimeMillis()+".jpg"); 99 | Map map = CodeUtil.generateCodeAndPic(); 100 | ImageIO.write((RenderedImage) map.get("codePic"), "jpeg", out); 101 | System.out.println("验证码的值为:"+map.get("code")); 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/utils/CommonUtil.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.utils; 2 | 3 | import java.security.MessageDigest; 4 | import java.text.ParseException; 5 | import java.text.SimpleDateFormat; 6 | import java.util.Date; 7 | 8 | /** 9 | * @ClassName CommonUtil 10 | * @Description TODO 通用工具类 11 | * @Author 小莫 12 | * @Date 2019/04/10 17:00 13 | * @Version 1.0 14 | **/ 15 | public class CommonUtil { 16 | /** 17 | *功能描述: 将一个时间戳转换成提示性时间字符串,如刚刚,1秒前 18 | * @Author 小莫 19 | * @Date 17:00 2019/04/10 20 | * @Param [d] 21 | * @return java.lang.String 22 | */ 23 | public static String convertTimeToFormat (String timeString) throws ParseException { 24 | //将时间字符串转化为日期 25 | SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 26 | Date d = dateFormat.parse(timeString); 27 | //将时间转化为毫秒来计算 28 | long curTime = System.currentTimeMillis() / (long) 1000; 29 | long timeStamp = d.getTime()/1000l; 30 | long time = curTime - timeStamp; 31 | 32 | if (time < 60 && time >= 0) { 33 | return "刚刚"; 34 | } else if (time >= 60 && time < 3600) { 35 | return time / 60 + "分钟前"; 36 | } else if (time >= 3600 && time < 3600 * 24) { 37 | return time / 3600 + "小时前"; 38 | } else if (time >= 3600 * 24 && time < 3600 * 24 * 30) { 39 | return time / 3600 / 24 + "天前"; 40 | } else if (time >= 3600 * 24 * 30 && time < 3600 * 24 * 30 * 12) { 41 | return time / 3600 / 24 / 30 + "个月前"; 42 | } else if (time >= 3600 * 24 * 30 * 12) { 43 | return time / 3600 / 24 / 30 / 12 + "年前"; 44 | } else { 45 | return "刚刚"; 46 | } 47 | } 48 | 49 | /** 50 | * md5常用工具类 51 | * @param data 52 | * @return 53 | */ 54 | public static String MD5(String data){ 55 | try { 56 | 57 | MessageDigest md5 = MessageDigest.getInstance("MD5"); 58 | byte [] array = md5.digest(data.getBytes("UTF-8")); 59 | StringBuilder sb = new StringBuilder(); 60 | for (byte item : array) { 61 | sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3)); 62 | } 63 | return sb.toString().toUpperCase(); 64 | 65 | }catch (Exception e){ 66 | e.printStackTrace(); 67 | } 68 | return null; 69 | 70 | } 71 | 72 | public static void main(String[] args) { 73 | String pwd = "123456"; 74 | String s = MD5(pwd); 75 | System.out.println("CommonUtil.main "+s); 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/utils/HttpUtils.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.utils; 2 | 3 | import com.google.gson.Gson; 4 | import org.apache.http.HttpEntity; 5 | import org.apache.http.HttpResponse; 6 | import org.apache.http.client.config.RequestConfig; 7 | import org.apache.http.client.methods.CloseableHttpResponse; 8 | import org.apache.http.client.methods.HttpGet; 9 | import org.apache.http.client.methods.HttpPost; 10 | import org.apache.http.entity.StringEntity; 11 | import org.apache.http.impl.client.CloseableHttpClient; 12 | import org.apache.http.impl.client.HttpClients; 13 | import org.apache.http.util.EntityUtils; 14 | 15 | import java.util.HashMap; 16 | import java.util.Map; 17 | 18 | /** 19 | * 封装http get post 20 | */ 21 | public class HttpUtils { 22 | 23 | private static final Gson gson = new Gson(); 24 | /** 25 | * get方法 26 | * @param url 27 | * @return 28 | */ 29 | public static Map doGet(String url){ 30 | 31 | Map map = new HashMap<>(); 32 | CloseableHttpClient httpClient = HttpClients.createDefault(); 33 | //设置参数 34 | RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000) //连接超时 35 | .setConnectionRequestTimeout(5000)//请求超时 36 | .setSocketTimeout(5000) 37 | .setRedirectsEnabled(true) //允许自动重定向 38 | .build(); 39 | 40 | HttpGet httpGet = new HttpGet(url); 41 | httpGet.setConfig(requestConfig); 42 | 43 | try{ 44 | // 获取请求响应结果 45 | HttpResponse httpResponse = httpClient.execute(httpGet); 46 | if(httpResponse.getStatusLine().getStatusCode() == 200){ 47 | //这里注意设置默认字节编码格式 为 utf-8 48 | String jsonResult = EntityUtils.toString(httpResponse.getEntity(),"UTF-8"); 49 | //解决乱码 50 | //jsonResult = new String(jsonResult.getBytes("ISO-8859-1"), "UTF-8"); 51 | map = gson.fromJson(jsonResult,map.getClass()); 52 | } 53 | 54 | }catch (Exception e){ 55 | e.printStackTrace(); 56 | }finally { 57 | try { 58 | httpClient.close(); 59 | }catch (Exception e){ 60 | e.printStackTrace(); 61 | } 62 | } 63 | return map; 64 | } 65 | 66 | /** 67 | * 封装post 68 | * @return 69 | */ 70 | public static String doPost(String url, String data, int timeout){ 71 | CloseableHttpClient httpClient = HttpClients.createDefault(); 72 | //超时设置 73 | RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(timeout) //连接超时 74 | .setConnectionRequestTimeout(timeout)//请求超时 75 | .setSocketTimeout(timeout) 76 | .setRedirectsEnabled(true) //允许自动重定向 77 | .build(); 78 | 79 | HttpPost httpPost = new HttpPost(url); 80 | httpPost.setConfig(requestConfig); 81 | httpPost.addHeader("Content-Type","text/html; charset=UTF-8"); 82 | 83 | if(data != null && data instanceof String){ //使用字符串传参 84 | StringEntity stringEntity = new StringEntity(data,"UTF-8"); 85 | httpPost.setEntity(stringEntity); 86 | } 87 | 88 | try{ 89 | CloseableHttpResponse httpResponse = httpClient.execute(httpPost); 90 | HttpEntity httpEntity = httpResponse.getEntity(); 91 | if(httpResponse.getStatusLine().getStatusCode() == 200){ 92 | String result = EntityUtils.toString(httpEntity,"utf-8"); 93 | return result; 94 | } 95 | }catch (Exception e){ 96 | e.printStackTrace(); 97 | }finally { 98 | try{ 99 | httpClient.close(); 100 | }catch (Exception e){ 101 | e.printStackTrace(); 102 | } 103 | } 104 | return null; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/utils/JwtUtils.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.utils; 2 | 3 | import com.xmlvhy.crawler.constant.CommonConstants; 4 | import com.xmlvhy.crawler.entity.Customer; 5 | import io.jsonwebtoken.Claims; 6 | import io.jsonwebtoken.Jwts; 7 | import io.jsonwebtoken.SignatureAlgorithm; 8 | 9 | import java.util.Date; 10 | 11 | /** 12 | * Author: 小莫 13 | * Date: 2019-02-14 15:06 14 | * Description:jwt校验工具类 15 | */ 16 | public class JwtUtils { 17 | 18 | /** 19 | *功能描述: 生成 jwt token 20 | * @Author 小莫 21 | * @Date 15:45 2019/02/14 22 | * @Param [user] 23 | * @return java.lang.String 24 | */ 25 | public static String geneJsonWebToken(Customer customer){ 26 | if (customer == null) { 27 | return null; 28 | } 29 | String token = Jwts.builder().setSubject(CommonConstants.JWT_SUBJECT) 30 | .claim("id", customer.getId()) 31 | .claim("name", customer.getName()) 32 | .claim("img", customer.getHeader()) 33 | .setIssuedAt(new Date()) 34 | .setExpiration(new Date(System.currentTimeMillis() + CommonConstants.JWT_TOKEN_EXPIRE_TIME)) 35 | .signWith(SignatureAlgorithm.HS256, CommonConstants.JWT_APPSECRET).compact(); 36 | return token; 37 | } 38 | 39 | /** 40 | *功能描述: 校验token 41 | * @Author 小莫 42 | * @Date 15:51 2019/02/14 43 | * @Param [token] 44 | * @return io.jsonwebtoken.Claims 45 | */ 46 | public static Claims checkJWT(String token){ 47 | try { 48 | final Claims claims = Jwts.parser().setSigningKey(CommonConstants.JWT_APPSECRET).parseClaimsJws(token).getBody(); 49 | return claims; 50 | }catch (Exception e){ 51 | return null; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/utils/OgnlUtil.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.utils; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import ognl.Ognl; 5 | import ognl.OgnlException; 6 | 7 | import java.math.BigDecimal; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | /** 13 | * @ClassName OgnlUtil 14 | * @Description TODO: 对象图导航工具类 15 | * @Author 小莫 16 | * @Date 2019/04/09 18:14 17 | * @Version 1.0 18 | **/ 19 | @Slf4j 20 | public class OgnlUtil { 21 | 22 | /** 23 | *功能描述: 获取字符串 24 | * @Author 小莫 25 | * @Date 18:17 2019/04/09 26 | * @Param [ognl, rootMap] 27 | * @return java.lang.String 28 | */ 29 | public static String getString(String ognl, Map rootMap){ 30 | try { 31 | return Ognl.getValue(ognl, rootMap).toString(); 32 | } catch (OgnlException e) { 33 | log.error("OGNL 获取字符串失败"); 34 | throw new RuntimeException(e); 35 | } 36 | } 37 | 38 | /** 39 | *功能描述: 获取Number字段,Number是所有数字的父类 40 | * @Author 小莫 41 | * @Date 18:20 2019/04/09 42 | * @Param [ognl, rootMap] 43 | * @return java.lang.Number 44 | */ 45 | public static Number getNumber(String ognl, Map rootMap){ 46 | Number result = null; 47 | try { 48 | Object value = Ognl.getValue(ognl, rootMap); 49 | if (value != null) { 50 | if (value instanceof Number) { 51 | result = (Number) value; 52 | }else if(value instanceof String){ 53 | //转化为数字 54 | result = new BigDecimal((String) value); 55 | } 56 | } 57 | } catch (OgnlException e) { 58 | log.error("OGNL获取数字失败"); 59 | throw new RuntimeException(e); 60 | } 61 | return result; 62 | } 63 | 64 | /** 65 | *功能描述: 获取 boolean 66 | * @Author 小莫 67 | * @Date 18:27 2019/04/09 68 | * @Param [ognl, root] 69 | * @return java.lang.Boolean 70 | */ 71 | public static Boolean getBoolean(String ognl , Map root){ 72 | Boolean result = null; 73 | try { 74 | Object val = Ognl.getValue(ognl , root); 75 | if(val != null){ 76 | if(val instanceof Boolean){ 77 | result = (Boolean) val; 78 | }else if(val instanceof String){ 79 | result = ((String)val).equalsIgnoreCase("true")?true:false; 80 | }else if(val instanceof Number){ 81 | if(((Number)val).intValue() == 1){ 82 | result = true; 83 | }else{ 84 | result = false; 85 | } 86 | } 87 | } 88 | } catch (OgnlException e) { 89 | log.error("OGNL 获取Boolean失败"); 90 | throw new RuntimeException(e); 91 | } 92 | return result; 93 | } 94 | 95 | /** 96 | * 获取List集合,里面每一个元素都是Map 97 | * @param ognl 98 | * @param root 99 | * @return 100 | */ 101 | public static List> getListMap (String ognl , Map root){ 102 | List> listMap = null; 103 | try { 104 | listMap = (List) Ognl.getValue(ognl , root); 105 | if(listMap == null){ 106 | listMap = new ArrayList(); 107 | } 108 | 109 | } catch (OgnlException e) { 110 | log.error("获取 list Map失败"); 111 | throw new RuntimeException(e); 112 | } 113 | return listMap; 114 | } 115 | 116 | /** 117 | * 获取list集合,里面每一个元素都是String 118 | * @param ognl 119 | * @param root 120 | * @return 121 | */ 122 | public static List getListString(String ognl , Map root){ 123 | List list = null; 124 | try { 125 | list = (List)Ognl.getValue(ognl , root); 126 | if(list == null){ 127 | list = new ArrayList(); 128 | } 129 | } catch (OgnlException e) { 130 | log.error("OGNL 获取list string失败"); 131 | throw new RuntimeException(e); 132 | } 133 | return list; 134 | } 135 | 136 | } 137 | -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/utils/QQHttpClientUtil.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.utils; 2 | 3 | import com.google.gson.Gson; 4 | import org.apache.http.HttpEntity; 5 | import org.apache.http.HttpResponse; 6 | import org.apache.http.client.config.RequestConfig; 7 | import org.apache.http.client.methods.HttpGet; 8 | import org.apache.http.impl.client.CloseableHttpClient; 9 | import org.apache.http.impl.client.HttpClients; 10 | import org.apache.http.util.EntityUtils; 11 | 12 | import java.io.IOException; 13 | import java.util.HashMap; 14 | import java.util.Map; 15 | 16 | /** 17 | * @ClassName QQHttpClientUtil 18 | * @Description TODO : QQ授权登录相关接口,httpclient 请求 19 | * @Author 小莫 20 | * @Date 2019/04/19 15:04 21 | * @Version 1.0 22 | **/ 23 | public class QQHttpClientUtil { 24 | 25 | private static Gson gson = new Gson(); 26 | 27 | /** 28 | *功能描述: 由于qq返回的结果,不是json,需要修改一下: 29 | * ( {"client_id":"YOUR_APPID","openid":"YOUR_OPENID"} ); 30 | * @Author 小莫 31 | * @Date 15:25 2019/04/19 32 | * @Param [result] 33 | * @return com.alibaba.fastjson.JSONObject 34 | */ 35 | private static String parseJSONStr(String result){ 36 | //截取 括号内的内容才是标准的json格式内容 37 | int startIndex = result.indexOf("("); 38 | int endIndex = result.lastIndexOf(")"); 39 | String ret = result.substring(startIndex + 1, endIndex); 40 | return ret; 41 | } 42 | 43 | /** 44 | * 获取 Access_Token 45 | * @param url 46 | * @return 47 | * @throws IOException 48 | */ 49 | public static String getAccessToken(String url) throws IOException { 50 | CloseableHttpClient client = HttpClients.createDefault(); 51 | String token = null; 52 | 53 | HttpGet httpGet = new HttpGet(url); 54 | HttpResponse response = client.execute(httpGet); 55 | HttpEntity entity = response.getEntity(); 56 | 57 | //这里注意,请求accessToken,qq返回的如下数据格式,需要单独解析: 58 | // access_token=YOUR_ACCESS_TOKEN&expires_in=3600 59 | 60 | if (entity != null) { 61 | String result = EntityUtils.toString(entity, "UTF-8"); 62 | if (result.indexOf("access_token") >= 0) { 63 | String[] array = result.split("&"); 64 | for (String str: array) 65 | if (str.indexOf("access_token") >= 0) { 66 | token = str.substring(str.indexOf("=") + 1); 67 | break; 68 | } 69 | } 70 | } 71 | 72 | httpGet.releaseConnection(); 73 | return token; 74 | } 75 | 76 | /** 77 | * 获取 OpenID 78 | * @param url 79 | * @return 80 | * @throws IOException 81 | */ 82 | //public static String getOpenID(String url) throws IOException { 83 | // JSONObject jsonObject = null; 84 | // CloseableHttpClient client = HttpClients.createDefault(); 85 | // 86 | // HttpGet httpGet = new HttpGet(url); 87 | // HttpResponse response = client.execute(httpGet); 88 | // HttpEntity entity = response.getEntity(); 89 | // 90 | // if (entity != null) { 91 | // String result = EntityUtils.toString(entity, "UTF-8"); 92 | // jsonObject = parseJSONP(result); 93 | // } 94 | // 95 | // httpGet.releaseConnection(); 96 | // if (jsonObject != null) 97 | // return jsonObject.getString("openid"); 98 | // else 99 | // return null; 100 | //} 101 | 102 | /** 103 | * 获取用户信息 104 | * @param url 105 | * @return 106 | * @throws IOException 107 | */ 108 | //public static JSONObject getUserInfo(String url) throws IOException { 109 | // JSONObject jsonObject = null; 110 | // CloseableHttpClient client = HttpClients.createDefault(); 111 | // 112 | // HttpGet httpGet = new HttpGet(url); 113 | // HttpResponse response = client.execute(httpGet); 114 | // HttpEntity entity = response.getEntity(); 115 | // 116 | // if (entity != null) { 117 | // String result = EntityUtils.toString(entity, "UTF-8"); 118 | // jsonObject = JSONObject.parseObject(result); 119 | // } 120 | // 121 | // httpGet.releaseConnection(); 122 | // return jsonObject; 123 | //} 124 | 125 | /** 126 | *功能描述: QQ 请求获取 openid userInfo 等接口 127 | * @Author 小莫 128 | * @Date 15:29 2019/04/19 129 | * @Param [url] 130 | * @return java.util.Map 131 | */ 132 | public static Map doGet(String url){ 133 | 134 | Map map = new HashMap<>(); 135 | CloseableHttpClient httpClient = HttpClients.createDefault(); 136 | //设置参数 137 | RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000) //连接超时 138 | .setConnectionRequestTimeout(4000)//请求超时 139 | .setSocketTimeout(4000) 140 | .setRedirectsEnabled(true) //允许自动重定向 141 | .build(); 142 | 143 | HttpGet httpGet = new HttpGet(url); 144 | httpGet.setConfig(requestConfig); 145 | 146 | try{ 147 | // 获取请求响应结果 148 | HttpResponse httpResponse = httpClient.execute(httpGet); 149 | if(httpResponse.getStatusLine().getStatusCode() == 200){ 150 | String result = EntityUtils.toString(httpResponse.getEntity()); 151 | //解决乱码 152 | result = new String(parseJSONStr(result).getBytes("ISO-8859-1"), "UTF-8"); 153 | 154 | map = gson.fromJson(result,map.getClass()); 155 | } 156 | 157 | }catch (Exception e){ 158 | e.printStackTrace(); 159 | }finally { 160 | try { 161 | httpClient.close(); 162 | }catch (Exception e){ 163 | e.printStackTrace(); 164 | } 165 | } 166 | return map; 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /src/main/java/com/xmlvhy/crawler/vo/CustomerVo.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * @ClassName CustomerVo 9 | * @Description TODO 10 | * @Author 小莫 11 | * @Date 2019/04/12 21:47 12 | * @Version 1.0 13 | **/ 14 | @Data 15 | @AllArgsConstructor 16 | @NoArgsConstructor 17 | public class CustomerVo { 18 | private String loginName; 19 | private String password; 20 | private String name; 21 | private String sex; 22 | } 23 | -------------------------------------------------------------------------------- /src/main/resources/application-dev.properties: -------------------------------------------------------------------------------- 1 | server.port=8081 2 | ######################### 数据库基本配置 ############################### 3 | #utf8 与utf8mb4的区别。 4 | #1-4个字节, 1~保存数字 字母 2~3保存世界的各种语言 4~特殊符号 5 | #mysql中默认指定的utf-8最多只包含了3个字节。4个字节的时候会抛出一个异常,InCorrect String value 无法保存4个字节 6 | #在评论中包含了emoji表情符号 7 | #为了解决这个4个字节的问题,我们需要设置两个地方: 8 | #1.character_set_server与其他字符集都是utf8mb4 9 | #2.需要设置Tomcat 连接启动的初始化sql,注意 jdbc字符串增加 ?useUnicode=true 10 | 11 | ####################################################################### 12 | spring.datasource.driver-class-name=com.mysql.jdbc.Driver 13 | spring.datasource.url=jdbc:mysql://localhost:3306/crawler?useSSL=false&useUnicode=true&characterEncoding=utf-8 14 | spring.datasource.username= 15 | spring.datasource.password= 16 | 17 | ############# tomcat 配置###### 18 | spring.datasource.tomcat.init-s-q-l=SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci 19 | 20 | ############# 取消thymeleaf 缓存,让页面热部署,从而不需要修改页面每次重启工程,正式环境缓存开起来 ###### 21 | spring.thymeleaf.cache=false 22 | ##############log配置################ 23 | #将dao包下的日志最低级别调整为debug,即打印出sql语句 24 | logging.level.com.xmlvhy.crawler.dao=debug 25 | 26 | -------------------------------------------------------------------------------- /src/main/resources/application-pro.properties: -------------------------------------------------------------------------------- 1 | server.port=8082 2 | #日志配置 3 | #logging.level.root=info 4 | #logging.level.com.xmlvhy.crawler=info 5 | #logging.file=log/crawler-pro.log 6 | ######################### 数据库基本配置 ############################### 7 | 8 | #utf8 与utf8mb4的区别。 9 | #1-4个字节, 1~保存数字 字母 2~3保存世界的各种语言 4~特殊符号或emoji表情符号 10 | #mysql中默认指定的utf-8最多只包含了3个字节。4个字节的时候会抛出一个异常,InCorrect String value 无法保存4个字节 11 | #在评论中包含了emoji表情符号 12 | #为了解决这个4个字节的问题,我们需要设置两个地方: 13 | #1.character_set_server与其他字符集都是utf8mb4 14 | #2.需要设置Tomcat 连接启动的初始化sql,注意 jdbc字符串增加 ?useUnicode=true 15 | 16 | ####################################################################### 17 | spring.datasource.driver-class-name=com.mysql.jdbc.Driver 18 | spring.datasource.url=jdbc:mysql://localhost:3306/crawler?useSSL=false&useUnicode=true&characterEncoding=utf-8 19 | spring.datasource.username= 20 | spring.datasource.password= 21 | 22 | ############# tomcat 配置###### 23 | spring.datasource.tomcat.init-s-q-l=SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci 24 | 25 | ############# 取消thymeleaf 缓存,让页面热部署,从而不需要修改页面每次重启工程,正式环境缓存开起来 ###### 26 | spring.thymeleaf.cache=true -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | ##########基本配置######### 2 | spring.profiles.active=dev 3 | server.servlet.context-path=/crawler 4 | spring.devtools.restart.trigger-file=trigger.txt 5 | spring.banner.location=classpath:banner.txt 6 | spring.mvc.favicon.enabled=false 7 | spring.messages.basename=i18n/messages 8 | #################数据库连接池通用配置############### 9 | spring.datasource.initialSize=5 10 | spring.datasource.maxActive=100 11 | spring.datasource.minIdle=3 12 | spring.datasource.maxWait=50000 13 | ##################mybatis 配置####################### 14 | mybatis.type-aliases-package=com.xmlvhy.crawler.entity 15 | mybatis.mapper-locations=classpath:/mybatis/mapper/*.xml 16 | #分页插件配置,设置数据库方言,就是底层是哪种数据类型 17 | pagehelper.auto-dialect=mysql 18 | #查询合理化,如果查询页面小于1则查询第一页,如果查询页面大于最后一页则查询最后一页的数据 19 | pagehelper.reasonable=true 20 | ################ 爬虫相关参数。url 分别是 推荐,视频,图片和笑话#################### 21 | #备注:以下这四个api 爬取的数据已被加密,可以使用之前的接口来爬取 22 | #crawler.urls=http://s.budejie.com/v2/topic/list/1/{firstContentId}-{lastContentId}/budejie-android-8.0.5/0-25.json,http://s.budejie.com/v2/topic/list/41/{firstContentId}-{lastContentId}/budejie-android-8.0.5/0-25.json,http://s.budejie.com/v2/topic/list/10/{firstContentId}-{lastContentId}/budejie-android-8.0.5/0-25.json,http://s.budejie.com/v2/topic/list/29/{firstContentId}-{lastContentId}/budejie-android-8.0.5/0-25.json 23 | 24 | #旧的api有推荐、视频、图片、笑话、排行五个模块,np作为下一次爬取数据的url参数,也是每条爬取数据的np的值 25 | crawler.urls=http://c.api.budejie.com/topic/list/jingxuan/1/budejie-android-6.9.4/{np}-20.json?market=xiaomi&ver=6.9.4&visiting=&os=6.0&appname=baisibudejie&client=android&udid=864141036474044&mac=02%3A00%3A00%3A00%3A00%3A00,http://c.api.budejie.com/topic/list/jingxuan/41/budejie-android-6.9.4/{np}-20.json?market=xiaomi&ver=6.9.4&visiting=&os=6.0&appname=baisibudejie&client=android&udid=864141036474044&mac=02%3A00%3A00%3A00%3A00%3A00,http://c.api.budejie.com/topic/list/jingxuan/10/budejie-android-6.9.4/{np}-20.json?market=xiaomi&ver=6.9.4&visiting=&os=6.0&appname=baisibudejie&client=android&udid=864141036474044&mac=02%3A00%3A00%3A00%3A00%3A00,http://c.api.budejie.com/topic/list/jingxuan/29/budejie-android-6.9.4/{np}-20.json?market=xiaomi&ver=6.9.4&visiting=&os=6.0&appname=baisibudejie&client=android&udid=864141036474044&mac=02%3A00%3A00%3A00%3A00%3A00,http://s.budejie.com/topic/list/remen/1/budejie-android-6.9.4/{np}-20.json?market=xiaomi&ver=6.9.4&visiting=&os=6.0&appname=baisibudejie&client=android&udid=864141036474044&mac=02%3A00%3A00%3A00%3A00%3A00 26 | #爬取的允许出错的最大次数 27 | crawler.num=2 28 | #每个模块爬取的总条数 29 | crawler.crawlerSum=100 30 | #是否开启爬虫任务,0关闭,1开启 31 | crawler.enable=1 32 | 33 | ######################################################################################### 34 | # //任务执行的方法 35 | # //@Scheduled 注解用于指定当前方法是一个任务调度 cron表达式指定执行的间隔 36 | # //* * * * * ? 每秒执行一次 37 | # //秒 分 时 日 月 星期 38 | # //*代表任意时间 具体的数字代表精确值 ,用于多个值 /用于固定间隔 - 范围 ?忽略 39 | # //0 * 23 * * ? 每天23点~24点之间每分钟执行一次 40 | # //0 0 8-18 * ? 每天早上8点到下午六点,0份0秒准时执行一次 41 | # //0 0 0 */2 * ? 0 2 4 6 ... 22 0点0分执行 42 | # ######################################################################################## 43 | #设置任务执行的时间 44 | #每间隔 30分钟 执行一次 45 | crawler.cron=0 */1 * * * ? 46 | 47 | 48 | -------------------------------------------------------------------------------- /src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | o8888888o 2 | 88" . "88 3 | (| -_- |) 4 | O\ = /O 5 | ____/`---'\____ 6 | . ' \\| | `. 7 | / \\||| : ||| \ 8 | / _||||| -:- |||||- \ 9 | | | \\\ - / | | 10 | | \_| ''\---/'' | | 11 | \ .-\__ `-` ___/-. / 12 | ___`. .' /--.--\ `. . __ 13 | ."" '< `.___\_<|>_/___.' >'"". 14 | | | : `- \`.;`\ _ /`;.`/ - ` : | | 15 | \ \ `-. \_ __\ /__ _/ .-` / / 16 | ======`-.____`-.___\_____/___.-`____.-'====== 17 | `=---=' 18 | 19 | ............................................. 20 | 佛祖镇楼 BUG辟易 21 | 佛曰: 22 | 写字楼里写字间,写字间里程序员; 23 | 程序人员写程序,又拿程序换酒钱。 24 | 酒醒只在网上坐,酒醉还来网下眠; 25 | 酒醉酒醒日复日,网上网下年复年。 26 | 但愿老死电脑间,不愿鞠躬老板前; 27 | 奔驰宝马贵者趣,公交自行程序员。 28 | 别人笑我忒疯癫,我笑自己命太贱; -------------------------------------------------------------------------------- /src/main/resources/config.properties: -------------------------------------------------------------------------------- 1 | ################## 微信开放平台配置 ##################### 2 | wxopen.appid= 3 | wxopen.appsecret= 4 | #回调url 5 | wxopen.redirect_url=http://xiaomo.mynatapp.cc/crawler/weChat/callback 6 | #扫码登录调出微信二维码地址 7 | wxopen.qrcode_url=https://open.weixin.qq.com/connect/qrconnect?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_login&state=%s#wechat_redirect 8 | #微信获取accessToken的api 9 | wxopen.access_token_url=https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code 10 | #获取用户信息的的api 11 | wxopen.user_info_url=https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN 12 | 13 | 14 | ######################## QQ 授权登录相关配置 ######################### 15 | qq.app_id= 16 | qq.app_key= 17 | qq.redirect_url=https://xiaomo.mynatapp.cc/crawler/qq/login 18 | 19 | #qq授权页面 20 | qq.oauth_url=https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=%s&redirect_uri=%s&state=%s 21 | #获取accessToken 22 | qq.access_token_url=https://graph.qq.com/oauth2.0/token?grant_type=authorization_code&client_id=%s&client_secret=%s&code=%s&redirect_uri=%s 23 | #获取openId 24 | qq.open_id_url=https://graph.qq.com/oauth2.0/me?access_token=%s 25 | #通过openId 和 accessToken 获取用户信息 26 | qq.user_info_url=https://graph.qq.com/user/get_user_info?access_token=%s&oauth_consumer_key=%s&openid=%s -------------------------------------------------------------------------------- /src/main/resources/i18n/messages.properties: -------------------------------------------------------------------------------- 1 | login.defaultImage=https://www.xmlvhy.com/images/user.png 2 | login.accessPage= 3 | #本地 4 | qqLogin.redirectUrl= 5 | -------------------------------------------------------------------------------- /src/main/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | %d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] %logger{30} - %msg%n 21 | UTF-8 22 | 23 | 24 | 25 | 26 | 27 | 28 | %d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] %logger{30} - %msg%n 29 | UTF-8 30 | 31 | 32 | 33 | 34 | ${LOG_HOME}/crawler_%d{yyyy-MM-dd}.log 35 | 36 | 90 37 | 38 | 39 | 40 | INFO 41 | ACCEPT 42 | DENY 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /src/main/resources/mybatis/mapper/ChannelMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | channel_id, channel_name, sort_num 11 | 12 | 18 | 19 | delete from t_channel 20 | where channel_id = #{channelId,jdbcType=BIGINT} 21 | 22 | 23 | insert into t_channel (channel_id, channel_name, sort_num 24 | ) 25 | values (#{channelId,jdbcType=BIGINT}, #{channelName,jdbcType=VARCHAR}, #{sortNum,jdbcType=INTEGER} 26 | ) 27 | 28 | 29 | insert into t_channel 30 | 31 | 32 | channel_id, 33 | 34 | 35 | channel_name, 36 | 37 | 38 | sort_num, 39 | 40 | 41 | 42 | 43 | #{channelId,jdbcType=BIGINT}, 44 | 45 | 46 | #{channelName,jdbcType=VARCHAR}, 47 | 48 | 49 | #{sortNum,jdbcType=INTEGER}, 50 | 51 | 52 | 53 | 54 | update t_channel 55 | 56 | 57 | channel_name = #{channelName,jdbcType=VARCHAR}, 58 | 59 | 60 | sort_num = #{sortNum,jdbcType=INTEGER}, 61 | 62 | 63 | where channel_id = #{channelId,jdbcType=BIGINT} 64 | 65 | 66 | update t_channel 67 | set channel_name = #{channelName,jdbcType=VARCHAR}, 68 | sort_num = #{sortNum,jdbcType=INTEGER} 69 | where channel_id = #{channelId,jdbcType=BIGINT} 70 | 71 | -------------------------------------------------------------------------------- /src/main/resources/mybatis/mapper/CommentMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | comment_id, comment_text, uid, passtime, content_id 13 | 14 | 20 | 21 | delete from t_comment 22 | where comment_id = #{commentId,jdbcType=BIGINT} 23 | 24 | 25 | insert into t_comment (comment_id, comment_text, uid, 26 | passtime, content_id) 27 | values (#{commentId,jdbcType=BIGINT}, #{commentText,jdbcType=VARCHAR}, #{uid,jdbcType=BIGINT}, 28 | #{passtime,jdbcType=VARCHAR}, #{contentId,jdbcType=BIGINT}) 29 | 30 | 31 | insert into t_comment 32 | 33 | 34 | comment_id, 35 | 36 | 37 | comment_text, 38 | 39 | 40 | uid, 41 | 42 | 43 | passtime, 44 | 45 | 46 | content_id, 47 | 48 | 49 | 50 | 51 | #{commentId,jdbcType=BIGINT}, 52 | 53 | 54 | #{commentText,jdbcType=VARCHAR}, 55 | 56 | 57 | #{uid,jdbcType=BIGINT}, 58 | 59 | 60 | #{passtime,jdbcType=VARCHAR}, 61 | 62 | 63 | #{contentId,jdbcType=BIGINT}, 64 | 65 | 66 | 67 | 68 | update t_comment 69 | 70 | 71 | comment_text = #{commentText,jdbcType=VARCHAR}, 72 | 73 | 74 | uid = #{uid,jdbcType=BIGINT}, 75 | 76 | 77 | passtime = #{passtime,jdbcType=VARCHAR}, 78 | 79 | 80 | content_id = #{contentId,jdbcType=BIGINT}, 81 | 82 | 83 | where comment_id = #{commentId,jdbcType=BIGINT} 84 | 85 | 86 | update t_comment 87 | set comment_text = #{commentText,jdbcType=VARCHAR}, 88 | uid = #{uid,jdbcType=BIGINT}, 89 | passtime = #{passtime,jdbcType=VARCHAR}, 90 | content_id = #{contentId,jdbcType=BIGINT} 91 | where comment_id = #{commentId,jdbcType=BIGINT} 92 | 93 | 98 | -------------------------------------------------------------------------------- /src/main/resources/mybatis/mapper/CustomerMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | id, name, password, uid, nickname, header, login_name, sign, sex, create_time 18 | 19 | 25 | 26 | delete from t_customer 27 | where id = #{id,jdbcType=INTEGER} 28 | 29 | 30 | 31 | SELECT LAST_INSERT_ID() 32 | 33 | insert into t_customer (name, password, uid, 34 | nickname, header, login_name, 35 | sign, sex, create_time 36 | ) 37 | values (#{name,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, #{uid,jdbcType=VARCHAR}, 38 | #{nickname,jdbcType=VARCHAR}, #{header,jdbcType=VARCHAR}, #{loginName,jdbcType=VARCHAR}, 39 | #{sign,jdbcType=VARCHAR}, #{sex,jdbcType=VARCHAR}, #{createTime,jdbcType=TIMESTAMP} 40 | ) 41 | 42 | 43 | 44 | SELECT LAST_INSERT_ID() 45 | 46 | insert into t_customer 47 | 48 | 49 | name, 50 | 51 | 52 | password, 53 | 54 | 55 | uid, 56 | 57 | 58 | nickname, 59 | 60 | 61 | header, 62 | 63 | 64 | login_name, 65 | 66 | 67 | sign, 68 | 69 | 70 | sex, 71 | 72 | 73 | create_time, 74 | 75 | 76 | 77 | 78 | #{name,jdbcType=VARCHAR}, 79 | 80 | 81 | #{password,jdbcType=VARCHAR}, 82 | 83 | 84 | #{uid,jdbcType=VARCHAR}, 85 | 86 | 87 | #{nickname,jdbcType=VARCHAR}, 88 | 89 | 90 | #{header,jdbcType=VARCHAR}, 91 | 92 | 93 | #{loginName,jdbcType=VARCHAR}, 94 | 95 | 96 | #{sign,jdbcType=VARCHAR}, 97 | 98 | 99 | #{sex,jdbcType=VARCHAR}, 100 | 101 | 102 | #{createTime,jdbcType=TIMESTAMP}, 103 | 104 | 105 | 106 | 107 | update t_customer 108 | 109 | 110 | name = #{name,jdbcType=VARCHAR}, 111 | 112 | 113 | password = #{password,jdbcType=VARCHAR}, 114 | 115 | 116 | uid = #{uid,jdbcType=VARCHAR}, 117 | 118 | 119 | nickname = #{nickname,jdbcType=VARCHAR}, 120 | 121 | 122 | header = #{header,jdbcType=VARCHAR}, 123 | 124 | 125 | login_name = #{loginName,jdbcType=VARCHAR}, 126 | 127 | 128 | sign = #{sign,jdbcType=VARCHAR}, 129 | 130 | 131 | sex = #{sex,jdbcType=VARCHAR}, 132 | 133 | 134 | create_time = #{createTime,jdbcType=TIMESTAMP}, 135 | 136 | 137 | where id = #{id,jdbcType=INTEGER} 138 | 139 | 140 | update t_customer 141 | set name = #{name,jdbcType=VARCHAR}, 142 | password = #{password,jdbcType=VARCHAR}, 143 | uid = #{uid,jdbcType=VARCHAR}, 144 | nickname = #{nickname,jdbcType=VARCHAR}, 145 | header = #{header,jdbcType=VARCHAR}, 146 | login_name = #{loginName,jdbcType=VARCHAR}, 147 | sign = #{sign,jdbcType=VARCHAR}, 148 | sex = #{sex,jdbcType=VARCHAR}, 149 | create_time = #{createTime,jdbcType=TIMESTAMP} 150 | where id = #{id,jdbcType=INTEGER} 151 | 152 | 157 | 162 | 167 | -------------------------------------------------------------------------------- /src/main/resources/mybatis/mapper/ForumMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | forum_id, post_count, logo, forum_sort, forum_status, info, name, user_count 16 | 17 | 23 | 24 | delete from t_forum 25 | where forum_id = #{forumId,jdbcType=BIGINT} 26 | 27 | 28 | insert into t_forum (forum_id, post_count, logo, 29 | forum_sort, forum_status, info, 30 | name, user_count) 31 | values (#{forumId,jdbcType=BIGINT}, #{postCount,jdbcType=INTEGER}, #{logo,jdbcType=VARCHAR}, 32 | #{forumSort,jdbcType=INTEGER}, #{forumStatus,jdbcType=INTEGER}, #{info,jdbcType=VARCHAR}, 33 | #{name,jdbcType=VARCHAR}, #{userCount,jdbcType=INTEGER}) 34 | 35 | 36 | insert into t_forum 37 | 38 | 39 | forum_id, 40 | 41 | 42 | post_count, 43 | 44 | 45 | logo, 46 | 47 | 48 | forum_sort, 49 | 50 | 51 | forum_status, 52 | 53 | 54 | info, 55 | 56 | 57 | name, 58 | 59 | 60 | user_count, 61 | 62 | 63 | 64 | 65 | #{forumId,jdbcType=BIGINT}, 66 | 67 | 68 | #{postCount,jdbcType=INTEGER}, 69 | 70 | 71 | #{logo,jdbcType=VARCHAR}, 72 | 73 | 74 | #{forumSort,jdbcType=INTEGER}, 75 | 76 | 77 | #{forumStatus,jdbcType=INTEGER}, 78 | 79 | 80 | #{info,jdbcType=VARCHAR}, 81 | 82 | 83 | #{name,jdbcType=VARCHAR}, 84 | 85 | 86 | #{userCount,jdbcType=INTEGER}, 87 | 88 | 89 | 90 | 91 | update t_forum 92 | 93 | 94 | post_count = #{postCount,jdbcType=INTEGER}, 95 | 96 | 97 | logo = #{logo,jdbcType=VARCHAR}, 98 | 99 | 100 | forum_sort = #{forumSort,jdbcType=INTEGER}, 101 | 102 | 103 | forum_status = #{forumStatus,jdbcType=INTEGER}, 104 | 105 | 106 | info = #{info,jdbcType=VARCHAR}, 107 | 108 | 109 | name = #{name,jdbcType=VARCHAR}, 110 | 111 | 112 | user_count = #{userCount,jdbcType=INTEGER}, 113 | 114 | 115 | where forum_id = #{forumId,jdbcType=BIGINT} 116 | 117 | 118 | update t_forum 119 | set post_count = #{postCount,jdbcType=INTEGER}, 120 | logo = #{logo,jdbcType=VARCHAR}, 121 | forum_sort = #{forumSort,jdbcType=INTEGER}, 122 | forum_status = #{forumStatus,jdbcType=INTEGER}, 123 | info = #{info,jdbcType=VARCHAR}, 124 | name = #{name,jdbcType=VARCHAR}, 125 | user_count = #{userCount,jdbcType=INTEGER} 126 | where forum_id = #{forumId,jdbcType=BIGINT} 127 | 128 | -------------------------------------------------------------------------------- /src/main/resources/mybatis/mapper/ImageMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | image_id, big_url, watermarker_url, raw_height, raw_width, thumb_url, content_id 15 | 16 | 22 | 23 | delete from t_image 24 | where image_id = #{imageId,jdbcType=BIGINT} 25 | 26 | 27 | 28 | SELECT LAST_INSERT_ID() 29 | 30 | insert into t_image (big_url, watermarker_url, raw_height, 31 | raw_width, thumb_url, content_id 32 | ) 33 | values (#{bigUrl,jdbcType=VARCHAR}, #{watermarkerUrl,jdbcType=VARCHAR}, #{rawHeight,jdbcType=INTEGER}, 34 | #{rawWidth,jdbcType=INTEGER}, #{thumbUrl,jdbcType=VARCHAR}, #{contentId,jdbcType=BIGINT} 35 | ) 36 | 37 | 38 | 39 | SELECT LAST_INSERT_ID() 40 | 41 | insert into t_image 42 | 43 | 44 | big_url, 45 | 46 | 47 | watermarker_url, 48 | 49 | 50 | raw_height, 51 | 52 | 53 | raw_width, 54 | 55 | 56 | thumb_url, 57 | 58 | 59 | content_id, 60 | 61 | 62 | 63 | 64 | #{bigUrl,jdbcType=VARCHAR}, 65 | 66 | 67 | #{watermarkerUrl,jdbcType=VARCHAR}, 68 | 69 | 70 | #{rawHeight,jdbcType=INTEGER}, 71 | 72 | 73 | #{rawWidth,jdbcType=INTEGER}, 74 | 75 | 76 | #{thumbUrl,jdbcType=VARCHAR}, 77 | 78 | 79 | #{contentId,jdbcType=BIGINT}, 80 | 81 | 82 | 83 | 84 | update t_image 85 | 86 | 87 | big_url = #{bigUrl,jdbcType=VARCHAR}, 88 | 89 | 90 | watermarker_url = #{watermarkerUrl,jdbcType=VARCHAR}, 91 | 92 | 93 | raw_height = #{rawHeight,jdbcType=INTEGER}, 94 | 95 | 96 | raw_width = #{rawWidth,jdbcType=INTEGER}, 97 | 98 | 99 | thumb_url = #{thumbUrl,jdbcType=VARCHAR}, 100 | 101 | 102 | content_id = #{contentId,jdbcType=BIGINT}, 103 | 104 | 105 | where image_id = #{imageId,jdbcType=BIGINT} 106 | 107 | 108 | update t_image 109 | set big_url = #{bigUrl,jdbcType=VARCHAR}, 110 | watermarker_url = #{watermarkerUrl,jdbcType=VARCHAR}, 111 | raw_height = #{rawHeight,jdbcType=INTEGER}, 112 | raw_width = #{rawWidth,jdbcType=INTEGER}, 113 | thumb_url = #{thumbUrl,jdbcType=VARCHAR}, 114 | content_id = #{contentId,jdbcType=BIGINT} 115 | where image_id = #{imageId,jdbcType=BIGINT} 116 | 117 | 122 | -------------------------------------------------------------------------------- /src/main/resources/mybatis/mapper/SourceMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | source_id, channel_id, response_text, create_time, url, state 14 | 15 | 21 | 22 | 27 | 28 | 29 | delete from t_source 30 | where source_id = #{sourceId,jdbcType=BIGINT} 31 | 32 | 33 | 34 | SELECT LAST_INSERT_ID() 35 | 36 | insert into t_source (channel_id, response_text, create_time, 37 | url, state) 38 | values (#{channelId,jdbcType=BIGINT}, #{responseText,jdbcType=VARCHAR}, #{createTime,jdbcType=TIMESTAMP}, 39 | #{url,jdbcType=VARCHAR}, #{state,jdbcType=VARCHAR}) 40 | 41 | 42 | 43 | SELECT LAST_INSERT_ID() 44 | 45 | insert into t_source 46 | 47 | 48 | channel_id, 49 | 50 | 51 | response_text, 52 | 53 | 54 | create_time, 55 | 56 | 57 | url, 58 | 59 | 60 | state, 61 | 62 | 63 | 64 | 65 | #{channelId,jdbcType=BIGINT}, 66 | 67 | 68 | #{responseText,jdbcType=VARCHAR}, 69 | 70 | 71 | #{createTime,jdbcType=TIMESTAMP}, 72 | 73 | 74 | #{url,jdbcType=VARCHAR}, 75 | 76 | 77 | #{state,jdbcType=VARCHAR}, 78 | 79 | 80 | 81 | 82 | update t_source 83 | 84 | 85 | channel_id = #{channelId,jdbcType=BIGINT}, 86 | 87 | 88 | response_text = #{responseText,jdbcType=VARCHAR}, 89 | 90 | 91 | create_time = #{createTime,jdbcType=TIMESTAMP}, 92 | 93 | 94 | url = #{url,jdbcType=VARCHAR}, 95 | 96 | 97 | state = #{state,jdbcType=VARCHAR}, 98 | 99 | 100 | where source_id = #{sourceId,jdbcType=BIGINT} 101 | 102 | 103 | update t_source 104 | set channel_id = #{channelId,jdbcType=BIGINT}, 105 | response_text = #{responseText,jdbcType=VARCHAR}, 106 | create_time = #{createTime,jdbcType=TIMESTAMP}, 107 | url = #{url,jdbcType=VARCHAR}, 108 | state = #{state,jdbcType=VARCHAR} 109 | where source_id = #{sourceId,jdbcType=BIGINT} 110 | 111 | -------------------------------------------------------------------------------- /src/main/resources/mybatis/mapper/SourceMapper.xml.bak: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 10 | insert into t_source 11 | (channel_id, response_text, create_time, url, state) 12 | values 13 | (#{channelId},#{responseText},#{createTime},#{url},#{state}) 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/main/resources/mybatis/mapper/UserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | uid, header, is_vip, is_v, room_url, room_name, room_role, room_icon, nickname 17 | 18 | 24 | 25 | delete from t_user 26 | where uid = #{uid,jdbcType=BIGINT} 27 | 28 | 29 | insert into t_user (uid, header, is_vip, 30 | is_v, room_url, room_name, 31 | room_role, room_icon, nickname 32 | ) 33 | values (#{uid,jdbcType=BIGINT}, #{header,jdbcType=VARCHAR}, #{isVip,jdbcType=INTEGER}, 34 | #{isV,jdbcType=INTEGER}, #{roomUrl,jdbcType=VARCHAR}, #{roomName,jdbcType=VARCHAR}, 35 | #{roomRole,jdbcType=VARCHAR}, #{roomIcon,jdbcType=VARCHAR}, #{nickname,jdbcType=VARCHAR} 36 | ) 37 | 38 | 39 | insert into t_user 40 | 41 | 42 | uid, 43 | 44 | 45 | header, 46 | 47 | 48 | is_vip, 49 | 50 | 51 | is_v, 52 | 53 | 54 | room_url, 55 | 56 | 57 | room_name, 58 | 59 | 60 | room_role, 61 | 62 | 63 | room_icon, 64 | 65 | 66 | nickname, 67 | 68 | 69 | 70 | 71 | #{uid,jdbcType=BIGINT}, 72 | 73 | 74 | #{header,jdbcType=VARCHAR}, 75 | 76 | 77 | #{isVip,jdbcType=INTEGER}, 78 | 79 | 80 | #{isV,jdbcType=INTEGER}, 81 | 82 | 83 | #{roomUrl,jdbcType=VARCHAR}, 84 | 85 | 86 | #{roomName,jdbcType=VARCHAR}, 87 | 88 | 89 | #{roomRole,jdbcType=VARCHAR}, 90 | 91 | 92 | #{roomIcon,jdbcType=VARCHAR}, 93 | 94 | 95 | #{nickname,jdbcType=VARCHAR}, 96 | 97 | 98 | 99 | 100 | update t_user 101 | 102 | 103 | header = #{header,jdbcType=VARCHAR}, 104 | 105 | 106 | is_vip = #{isVip,jdbcType=INTEGER}, 107 | 108 | 109 | is_v = #{isV,jdbcType=INTEGER}, 110 | 111 | 112 | room_url = #{roomUrl,jdbcType=VARCHAR}, 113 | 114 | 115 | room_name = #{roomName,jdbcType=VARCHAR}, 116 | 117 | 118 | room_role = #{roomRole,jdbcType=VARCHAR}, 119 | 120 | 121 | room_icon = #{roomIcon,jdbcType=VARCHAR}, 122 | 123 | 124 | nickname = #{nickname,jdbcType=VARCHAR}, 125 | 126 | 127 | where uid = #{uid,jdbcType=BIGINT} 128 | 129 | 130 | update t_user 131 | set header = #{header,jdbcType=VARCHAR}, 132 | is_vip = #{isVip,jdbcType=INTEGER}, 133 | is_v = #{isV,jdbcType=INTEGER}, 134 | room_url = #{roomUrl,jdbcType=VARCHAR}, 135 | room_name = #{roomName,jdbcType=VARCHAR}, 136 | room_role = #{roomRole,jdbcType=VARCHAR}, 137 | room_icon = #{roomIcon,jdbcType=VARCHAR}, 138 | nickname = #{nickname,jdbcType=VARCHAR} 139 | where uid = #{uid,jdbcType=BIGINT} 140 | 141 | -------------------------------------------------------------------------------- /src/main/resources/mybatis/mbg.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 18 | 19 | 20 | 21 | 24 | 25 | 26 | 27 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 86 | 87 |
88 |
89 |
-------------------------------------------------------------------------------- /src/main/resources/static/css/crawler.css: -------------------------------------------------------------------------------- 1 | body { 2 | overflow: hidden; 3 | } 4 | 5 | .video-player { 6 | background-color: transparent; 7 | display: block; 8 | position: absolute; 9 | z-index: 1; 10 | top: 0; 11 | } 12 | 13 | .video_mask { 14 | width: 100%; 15 | height: 100%; 16 | position: absolute; 17 | left: 0; 18 | top: 0; 19 | z-index: 90; 20 | } 21 | 22 | .login, .register { 23 | height: 350px; 24 | width: 260px; 25 | padding: 20px; 26 | background-color: rgba(0, 0, 0, 0.3); 27 | border-radius: 4px; 28 | position: absolute; 29 | left: 50%; 30 | top: 50%; 31 | margin: -150px 0 0 -150px; 32 | z-index: 99; 33 | } 34 | 35 | .login h1, .register h1 { 36 | text-align: center; 37 | color: #fff; 38 | font-size: 24px; 39 | margin-bottom: 20px; 40 | } 41 | 42 | .form_code { 43 | position: relative; 44 | } 45 | 46 | .form_code .code { 47 | position: absolute; 48 | right: 0; 49 | top: 1px; 50 | cursor: pointer; 51 | } 52 | 53 | .login_btn { 54 | width: 100%; 55 | } 56 | 57 | /*im*/ 58 | .chat_login_btn { 59 | width: 48%; 60 | } 61 | 62 | .chat_register_btn { 63 | width: 48%; 64 | } 65 | 66 | .chat_login_btn, .chat_register_btn { 67 | background-color: rgb(52, 179, 175); 68 | } 69 | 70 | .right { 71 | float: right; 72 | } 73 | 74 | .register { 75 | height: 360px; 76 | } 77 | 78 | .back-ground { 79 | background-color: transparent; 80 | display: block; 81 | position: absolute; 82 | z-index: 1; 83 | top: 0; 84 | } 85 | 86 | /*复选*/ 87 | .layui-form-checkbox[lay-skin="primary"] span { 88 | color: white; 89 | } 90 | 91 | .layui-form-checkbox[lay-skin="primary"]:hover i { 92 | border-color: rgb(52, 179, 175); 93 | color: #fff; 94 | } 95 | 96 | .layui-form-checked[lay-skin="primary"] i { 97 | border-color: rgb(52, 179, 175); 98 | background-color: rgb(52, 179, 175); 99 | color: #fff; 100 | } 101 | 102 | /*单选*/ 103 | .layui-form-radio span { 104 | color: white; 105 | } 106 | 107 | .layui-form-radio:hover i { 108 | border-color: #5FB878; 109 | } 110 | 111 | .layui-form-radio > i:hover, .layui-form-radioed > i { 112 | color: #5FB878; 113 | } 114 | 115 | .forget-password { 116 | padding: 0; 117 | color: white; 118 | cursor: pointer; 119 | margin-left: 200px; 120 | } 121 | 122 | .forget-password:hover { 123 | color: rgb(52, 179, 175); 124 | } 125 | -------------------------------------------------------------------------------- /src/main/resources/static/css/error.css: -------------------------------------------------------------------------------- 1 | /* 搜集整理 www.198zone.com */ 2 | body, div { 3 | margin: 0; 4 | padding: 0; 5 | } 6 | body { 7 | background: url("../images/error_bg.jpg") repeat-x scroll 0 0 #67ACE4; 8 | } 9 | #container { 10 | margin: 0 auto; 11 | padding-top: 50px; 12 | text-align: center; 13 | width: 560px; 14 | } 15 | #container img { 16 | border: medium none; 17 | margin-bottom: 50px; 18 | } 19 | #container .error { 20 | height: 200px; 21 | position: relative; 22 | } 23 | #container .error img { 24 | bottom: -50px; 25 | position: absolute; 26 | right: -50px; 27 | } 28 | #container .msg { 29 | margin-bottom: 65px; 30 | } 31 | #cloud { 32 | background: url("../images/error_cloud.png") repeat-x scroll 0 0 transparent; 33 | bottom: 0; 34 | height: 170px; 35 | position: absolute; 36 | width: 100%; 37 | } -------------------------------------------------------------------------------- /src/main/resources/static/css/login.css: -------------------------------------------------------------------------------- 1 | body { 2 | overflow: hidden; 3 | } 4 | 5 | .video-player { 6 | background-color: transparent; 7 | display: block; 8 | position: absolute; 9 | z-index: 1; 10 | top: 0; 11 | } 12 | 13 | .video_mask { 14 | width: 100%; 15 | height: 100%; 16 | position: absolute; 17 | left: 0; 18 | top: 0; 19 | z-index: 90; 20 | background-color: rgba(0, 0, 0, 0.5); 21 | } 22 | 23 | .login, .register { 24 | height: 300px; 25 | width: 260px; 26 | padding: 20px; 27 | background-color: rgba(0, 0, 0, 0.3); 28 | border-radius: 4px; 29 | position: absolute; 30 | left: 50%; 31 | top: 50%; 32 | margin: -150px 0 0 -150px; 33 | z-index: 99; 34 | } 35 | 36 | .login h1, .register h1 { 37 | text-align: center; 38 | color: #fff; 39 | font-size: 24px; 40 | margin-bottom: 20px; 41 | } 42 | 43 | .form_code { 44 | position: relative; 45 | } 46 | 47 | .form_code .code { 48 | position: absolute; 49 | right: 0; 50 | top: 1px; 51 | cursor: pointer; 52 | } 53 | 54 | .login_btn { 55 | width: 100%; 56 | } -------------------------------------------------------------------------------- /src/main/resources/static/css/me.css: -------------------------------------------------------------------------------- 1 | .toolbar { 2 | margin-top: 10px; 3 | } 4 | 5 | .toolbar i { 6 | font-size: 14px; 7 | margin-right: 10px; 8 | cursor: pointer; 9 | } 10 | 11 | .toolbar i > span { 12 | margin-left: 5px; 13 | font-size: 14px; 14 | } 15 | 16 | .layui-row { 17 | padding: 5px; 18 | padding-left: 20px 19 | } 20 | 21 | .forum-title { 22 | width: auto; 23 | margin-left: 80px; 24 | font-size: 18px; 25 | font-weight: bold; 26 | } 27 | 28 | .forum-subtitle { 29 | width: auto; 30 | margin-left: 80px; 31 | color: #aaa; 32 | overflow: hidden; 33 | text-overflow: ellipsis; 34 | white-space: nowrap; 35 | box-sizing: border-box; 36 | } 37 | 38 | .forum-icon { 39 | width: 64px; 40 | border-radius: 5px; 41 | float: left 42 | } 43 | 44 | .comment-text { 45 | width: auto; 46 | margin-left: 40px; 47 | font-size: 12px; 48 | padding-left: 10px 49 | } 50 | 51 | .comment-icon { 52 | width: 32px; 53 | border-radius: 16px; 54 | float: left 55 | } 56 | 57 | .video { 58 | width: 100%; 59 | height: auto; 60 | } -------------------------------------------------------------------------------- /src/main/resources/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/favicon.ico -------------------------------------------------------------------------------- /src/main/resources/static/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /src/main/resources/static/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /src/main/resources/static/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /src/main/resources/static/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /src/main/resources/static/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /src/main/resources/static/images/404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/images/404.png -------------------------------------------------------------------------------- /src/main/resources/static/images/404_msg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/images/404_msg.png -------------------------------------------------------------------------------- /src/main/resources/static/images/404_to_index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/images/404_to_index.png -------------------------------------------------------------------------------- /src/main/resources/static/images/error_bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/images/error_bg.jpg -------------------------------------------------------------------------------- /src/main/resources/static/images/error_cloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/images/error_cloud.png -------------------------------------------------------------------------------- /src/main/resources/static/images/image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/images/image.jpg -------------------------------------------------------------------------------- /src/main/resources/static/images/login_bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/images/login_bg.jpg -------------------------------------------------------------------------------- /src/main/resources/static/layui/css/modules/code.css: -------------------------------------------------------------------------------- 1 | /** layui-v2.4.5 MIT License By https://www.layui.com */ 2 | html #layuicss-skincodecss{display:none;position:absolute;width:1989px}.layui-code-h3,.layui-code-view{position:relative;font-size:12px}.layui-code-view{display:block;margin:10px 0;padding:0;border:1px solid #e2e2e2;border-left-width:6px;background-color:#F2F2F2;color:#333;font-family:Courier New}.layui-code-h3{padding:0 10px;height:32px;line-height:32px;border-bottom:1px solid #e2e2e2}.layui-code-h3 a{position:absolute;right:10px;top:0;color:#999}.layui-code-view .layui-code-ol{position:relative;overflow:auto}.layui-code-view .layui-code-ol li{position:relative;margin-left:45px;line-height:20px;padding:0 5px;border-left:1px solid #e2e2e2;list-style-type:decimal-leading-zero;*list-style-type:decimal;background-color:#fff}.layui-code-view pre{margin:0}.layui-code-notepad{border:1px solid #0C0C0C;border-left-color:#3F3F3F;background-color:#0C0C0C;color:#C2BE9E}.layui-code-notepad .layui-code-h3{border-bottom:none}.layui-code-notepad .layui-code-ol li{background-color:#3F3F3F;border-left:none} -------------------------------------------------------------------------------- /src/main/resources/static/layui/css/modules/layer/default/icon-ext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/css/modules/layer/default/icon-ext.png -------------------------------------------------------------------------------- /src/main/resources/static/layui/css/modules/layer/default/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/css/modules/layer/default/icon.png -------------------------------------------------------------------------------- /src/main/resources/static/layui/css/modules/layer/default/loading-0.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/css/modules/layer/default/loading-0.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/css/modules/layer/default/loading-1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/css/modules/layer/default/loading-1.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/css/modules/layer/default/loading-2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/css/modules/layer/default/loading-2.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/font/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/font/iconfont.eot -------------------------------------------------------------------------------- /src/main/resources/static/layui/font/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/font/iconfont.ttf -------------------------------------------------------------------------------- /src/main/resources/static/layui/font/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/font/iconfont.woff -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/0.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/0.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/1.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/10.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/10.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/11.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/11.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/12.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/12.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/13.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/13.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/14.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/14.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/15.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/15.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/16.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/16.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/17.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/17.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/18.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/18.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/19.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/19.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/2.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/20.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/20.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/21.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/21.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/22.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/22.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/23.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/23.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/24.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/24.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/25.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/25.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/26.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/26.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/27.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/27.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/28.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/28.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/29.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/29.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/3.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/30.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/30.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/31.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/31.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/32.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/32.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/33.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/33.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/34.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/34.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/35.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/35.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/36.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/36.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/37.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/37.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/38.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/38.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/39.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/39.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/4.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/40.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/40.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/41.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/41.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/42.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/42.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/43.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/43.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/44.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/44.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/45.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/45.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/46.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/46.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/47.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/47.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/48.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/48.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/49.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/49.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/5.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/5.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/50.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/50.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/51.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/51.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/52.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/52.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/53.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/53.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/54.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/54.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/55.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/55.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/56.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/56.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/57.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/57.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/58.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/58.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/59.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/59.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/6.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/6.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/60.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/60.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/61.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/61.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/62.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/62.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/63.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/63.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/64.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/64.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/65.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/65.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/66.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/66.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/67.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/67.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/68.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/68.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/69.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/69.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/7.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/7.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/70.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/70.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/71.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/71.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/8.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/8.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/images/face/9.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhijun/springboot-crawler/283dfed13e07d84628455a6420cdcd9deb372a66/src/main/resources/static/layui/images/face/9.gif -------------------------------------------------------------------------------- /src/main/resources/static/layui/lay/modules/carousel.js: -------------------------------------------------------------------------------- 1 | /** layui-v2.4.5 MIT License By https://www.layui.com */ 2 | ;layui.define("jquery",function(e){"use strict";var i=layui.$,n=(layui.hint(),layui.device(),{config:{},set:function(e){var n=this;return n.config=i.extend({},n.config,e),n},on:function(e,i){return layui.onevent.call(this,t,e,i)}}),t="carousel",a="layui-this",l=">*[carousel-item]>*",o="layui-carousel-left",r="layui-carousel-right",d="layui-carousel-prev",s="layui-carousel-next",u="layui-carousel-arrow",c="layui-carousel-ind",m=function(e){var t=this;t.config=i.extend({},t.config,n.config,e),t.render()};m.prototype.config={width:"600px",height:"280px",full:!1,arrow:"hover",indicator:"inside",autoplay:!0,interval:3e3,anim:"",trigger:"click",index:0},m.prototype.render=function(){var e=this,n=e.config;n.elem=i(n.elem),n.elem[0]&&(e.elemItem=n.elem.find(l),n.index<0&&(n.index=0),n.index>=e.elemItem.length&&(n.index=e.elemItem.length-1),n.interval<800&&(n.interval=800),n.full?n.elem.css({position:"fixed",width:"100%",height:"100%",zIndex:9999}):n.elem.css({width:n.width,height:n.height}),n.elem.attr("lay-anim",n.anim),e.elemItem.eq(n.index).addClass(a),e.elemItem.length<=1||(e.indicator(),e.arrow(),e.autoplay(),e.events()))},m.prototype.reload=function(e){var n=this;clearInterval(n.timer),n.config=i.extend({},n.config,e),n.render()},m.prototype.prevIndex=function(){var e=this,i=e.config,n=i.index-1;return n<0&&(n=e.elemItem.length-1),n},m.prototype.nextIndex=function(){var e=this,i=e.config,n=i.index+1;return n>=e.elemItem.length&&(n=0),n},m.prototype.addIndex=function(e){var i=this,n=i.config;e=e||1,n.index=n.index+e,n.index>=i.elemItem.length&&(n.index=0)},m.prototype.subIndex=function(e){var i=this,n=i.config;e=e||1,n.index=n.index-e,n.index<0&&(n.index=i.elemItem.length-1)},m.prototype.autoplay=function(){var e=this,i=e.config;i.autoplay&&(e.timer=setInterval(function(){e.slide()},i.interval))},m.prototype.arrow=function(){var e=this,n=e.config,t=i(['",'"].join(""));n.elem.attr("lay-arrow",n.arrow),n.elem.find("."+u)[0]&&n.elem.find("."+u).remove(),n.elem.append(t),t.on("click",function(){var n=i(this),t=n.attr("lay-type");e.slide(t)})},m.prototype.indicator=function(){var e=this,n=e.config,t=e.elemInd=i(['
    ',function(){var i=[];return layui.each(e.elemItem,function(e){i.push("")}),i.join("")}(),"
"].join(""));n.elem.attr("lay-indicator",n.indicator),n.elem.find("."+c)[0]&&n.elem.find("."+c).remove(),n.elem.append(t),"updown"===n.anim&&t.css("margin-top",-(t.height()/2)),t.find("li").on("hover"===n.trigger?"mouseover":n.trigger,function(){var t=i(this),a=t.index();a>n.index?e.slide("add",a-n.index):a/g,">").replace(/'/g,"'").replace(/"/g,""")),c.html('
  1. '+o.replace(/[\r\t\n]+/g,"
  2. ")+"
"),c.find(">.layui-code-h3")[0]||c.prepend('

'+(c.attr("lay-title")||e.title||"code")+(e.about?'layui.code':"")+"

");var d=c.find(">.layui-code-ol");c.addClass("layui-box layui-code-view"),(c.attr("lay-skin")||e.skin)&&c.addClass("layui-code-"+(c.attr("lay-skin")||e.skin)),(d.find("li").length/100|0)>0&&d.css("margin-left",(d.find("li").length/100|0)+"px"),(c.attr("lay-height")||e.height)&&d.css("max-height",c.attr("lay-height")||e.height)})})}).addcss("modules/code.css","skincodecss"); -------------------------------------------------------------------------------- /src/main/resources/static/layui/lay/modules/flow.js: -------------------------------------------------------------------------------- 1 | /** layui-v2.4.5 MIT License By https://www.layui.com */ 2 | ;layui.define("jquery",function(e){"use strict";var l=layui.$,o=function(e){},t='';o.prototype.load=function(e){var o,i,n,r,a=this,c=0;e=e||{};var f=l(e.elem);if(f[0]){var m=l(e.scrollElem||document),u=e.mb||50,s=!("isAuto"in e)||e.isAuto,v=e.end||"没有更多了",y=e.scrollElem&&e.scrollElem!==document,d="加载更多",h=l('");f.find(".layui-flow-more")[0]||f.append(h);var p=function(e,t){e=l(e),h.before(e),t=0==t||null,t?h.html(v):h.find("a").html(d),i=t,o=null,n&&n()},g=function(){o=!0,h.find("a").html(t),"function"==typeof e.done&&e.done(++c,p)};if(g(),h.find("a").on("click",function(){l(this);i||o||g()}),e.isLazyimg)var n=a.lazyimg({elem:e.elem+" img",scrollElem:e.scrollElem});return s?(m.on("scroll",function(){var e=l(this),t=e.scrollTop();r&&clearTimeout(r),i||(r=setTimeout(function(){var i=y?e.height():l(window).height(),n=y?e.prop("scrollHeight"):document.documentElement.scrollHeight;n-t-i<=u&&(o||g())},100))}),a):a}},o.prototype.lazyimg=function(e){var o,t=this,i=0;e=e||{};var n=l(e.scrollElem||document),r=e.elem||"img",a=e.scrollElem&&e.scrollElem!==document,c=function(e,l){var o=n.scrollTop(),r=o+l,c=a?function(){return e.offset().top-n.offset().top+o}():e.offset().top;if(c>=o&&c<=r&&!e.attr("src")){var m=e.attr("lay-src");layui.img(m,function(){var l=t.lazyimg.elem.eq(i);e.attr("src",m).removeAttr("lay-src"),l[0]&&f(l),i++})}},f=function(e,o){var f=a?(o||n).height():l(window).height(),m=n.scrollTop(),u=m+f;if(t.lazyimg.elem=l(r),e)c(e,f);else for(var s=0;su)break}};if(f(),!o){var m;n.on("scroll",function(){var e=l(this);m&&clearTimeout(m),m=setTimeout(function(){f(null,e)},50)}),o=!0}return f},e("flow",new o)}); -------------------------------------------------------------------------------- /src/main/resources/static/layui/lay/modules/laypage.js: -------------------------------------------------------------------------------- 1 | /** layui-v2.4.5 MIT License By https://www.layui.com */ 2 | ;layui.define(function(e){"use strict";var a=document,t="getElementById",n="getElementsByTagName",i="laypage",r="layui-disabled",u=function(e){var a=this;a.config=e||{},a.config.index=++s.index,a.render(!0)};u.prototype.type=function(){var e=this.config;if("object"==typeof e.elem)return void 0===e.elem.length?2:3},u.prototype.view=function(){var e=this,a=e.config,t=a.groups="groups"in a?0|a.groups:5;a.layout="object"==typeof a.layout?a.layout:["prev","page","next"],a.count=0|a.count,a.curr=0|a.curr||1,a.limits="object"==typeof a.limits?a.limits:[10,20,30,40,50],a.limit=0|a.limit||10,a.pages=Math.ceil(a.count/a.limit)||1,a.curr>a.pages&&(a.curr=a.pages),t<0?t=1:t>a.pages&&(t=a.pages),a.prev="prev"in a?a.prev:"上一页",a.next="next"in a?a.next:"下一页";var n=a.pages>t?Math.ceil((a.curr+(t>1?1:0))/(t>0?t:1)):1,i={prev:function(){return a.prev?''+a.prev+"":""}(),page:function(){var e=[];if(a.count<1)return"";n>1&&a.first!==!1&&0!==t&&e.push(''+(a.first||1)+"");var i=Math.floor((t-1)/2),r=n>1?a.curr-i:1,u=n>1?function(){var e=a.curr+(t-i-1);return e>a.pages?a.pages:e}():t;for(u-r2&&e.push('');r<=u;r++)r===a.curr?e.push('"+r+""):e.push(''+r+"");return a.pages>t&&a.pages>u&&a.last!==!1&&(u+1…'),0!==t&&e.push(''+(a.last||a.pages)+"")),e.join("")}(),next:function(){return a.next?''+a.next+"":""}(),count:'共 '+a.count+" 条",limit:function(){var e=['"}(),refresh:['','',""].join(""),skip:function(){return['到第','','页',""].join("")}()};return['
',function(){var e=[];return layui.each(a.layout,function(a,t){i[t]&&e.push(i[t])}),e.join("")}(),"
"].join("")},u.prototype.jump=function(e,a){if(e){var t=this,i=t.config,r=e.children,u=e[n]("button")[0],l=e[n]("input")[0],p=e[n]("select")[0],c=function(){var e=0|l.value.replace(/\s|\D/g,"");e&&(i.curr=e,t.render())};if(a)return c();for(var o=0,y=r.length;oi.pages||(i.curr=e,t.render())});p&&s.on(p,"change",function(){var e=this.value;i.curr*e>i.count&&(i.curr=Math.ceil(i.count/e)),i.limit=e,t.render()}),u&&s.on(u,"click",function(){c()})}},u.prototype.skip=function(e){if(e){var a=this,t=e[n]("input")[0];t&&s.on(t,"keyup",function(t){var n=this.value,i=t.keyCode;/^(37|38|39|40)$/.test(i)||(/\D/.test(n)&&(this.value=n.replace(/\D/,"")),13===i&&a.jump(e,!0))})}},u.prototype.render=function(e){var n=this,i=n.config,r=n.type(),u=n.view();2===r?i.elem&&(i.elem.innerHTML=u):3===r?i.elem.html(u):a[t](i.elem)&&(a[t](i.elem).innerHTML=u),i.jump&&i.jump(i,e);var s=a[t]("layui-laypage-"+i.index);n.jump(s),i.hash&&!e&&(location.hash="!"+i.hash+"="+i.curr),n.skip(s)};var s={render:function(e){var a=new u(e);return a.index},index:layui.laypage?layui.laypage.index+1e4:0,on:function(e,a,t){return e.attachEvent?e.attachEvent("on"+a,function(a){a.target=a.srcElement,t.call(e,a)}):e.addEventListener(a,t,!1),this}};e(i,s)}); -------------------------------------------------------------------------------- /src/main/resources/static/layui/lay/modules/laytpl.js: -------------------------------------------------------------------------------- 1 | /** layui-v2.4.5 MIT License By https://www.layui.com */ 2 | ;layui.define(function(e){"use strict";var r={open:"{{",close:"}}"},c={exp:function(e){return new RegExp(e,"g")},query:function(e,c,t){var o=["#([\\s\\S])+?","([^{#}])*?"][e||0];return n((c||"")+r.open+o+r.close+(t||""))},escape:function(e){return String(e||"").replace(/&(?!#?[a-zA-Z0-9]+;)/g,"&").replace(//g,">").replace(/'/g,"'").replace(/"/g,""")},error:function(e,r){var c="Laytpl Error:";return"object"==typeof console&&console.error(c+e+"\n"+(r||"")),c+e}},n=c.exp,t=function(e){this.tpl=e};t.pt=t.prototype,window.errors=0,t.pt.parse=function(e,t){var o=this,p=e,a=n("^"+r.open+"#",""),l=n(r.close+"$","");e=e.replace(/\s+|\r|\t|\n/g," ").replace(n(r.open+"#"),r.open+"# ").replace(n(r.close+"}"),"} "+r.close).replace(/\\/g,"\\\\").replace(n(r.open+"!(.+?)!"+r.close),function(e){return e=e.replace(n("^"+r.open+"!"),"").replace(n("!"+r.close),"").replace(n(r.open+"|"+r.close),function(e){return e.replace(/(.)/g,"\\$1")})}).replace(/(?="|')/g,"\\").replace(c.query(),function(e){return e=e.replace(a,"").replace(l,""),'";'+e.replace(/\\/g,"")+';view+="'}).replace(c.query(1),function(e){var c='"+(';return e.replace(/\s/g,"")===r.open+r.close?"":(e=e.replace(n(r.open+"|"+r.close),""),/^=/.test(e)&&(e=e.replace(/^=/,""),c='"+_escape_('),c+e.replace(/\\/g,"")+')+"')}),e='"use strict";var view = "'+e+'";return view;';try{return o.cache=e=new Function("d, _escape_",e),e(t,c.escape)}catch(u){return delete o.cache,c.error(u,p)}},t.pt.render=function(e,r){var n,t=this;return e?(n=t.cache?t.cache(e,c.escape):t.parse(t.tpl,e),r?void r(n):n):c.error("no data")};var o=function(e){return"string"!=typeof e?c.error("Template not found"):new t(e)};o.config=function(e){e=e||{};for(var c in e)r[c]=e[c]},o.v="1.2.0",e("laytpl",o)}); -------------------------------------------------------------------------------- /src/main/resources/static/layui/lay/modules/rate.js: -------------------------------------------------------------------------------- 1 | /** layui-v2.4.5 MIT License By https://www.layui.com */ 2 | ;layui.define("jquery",function(e){"use strict";var a=layui.jquery,i={config:{},index:layui.rate?layui.rate.index+1e4:0,set:function(e){var i=this;return i.config=a.extend({},i.config,e),i},on:function(e,a){return layui.onevent.call(this,n,e,a)}},l=function(){var e=this,a=e.config;return{setvalue:function(a){e.setvalue.call(e,a)},config:a}},n="rate",t="layui-rate",o="layui-icon-rate",s="layui-icon-rate-solid",u="layui-icon-rate-half",r="layui-icon-rate-solid layui-icon-rate-half",c="layui-icon-rate-solid layui-icon-rate",f="layui-icon-rate layui-icon-rate-half",v=function(e){var l=this;l.index=++i.index,l.config=a.extend({},l.config,i.config,e),l.render()};v.prototype.config={length:5,text:!1,readonly:!1,half:!1,value:0,theme:""},v.prototype.render=function(){var e=this,i=e.config,l=i.theme?'style="color: '+i.theme+';"':"";i.elem=a(i.elem),parseInt(i.value)!==i.value&&(i.half||(i.value=Math.ceil(i.value)-i.value<.5?Math.ceil(i.value):Math.floor(i.value)));for(var n='
    ",u=1;u<=i.length;u++){var r='
  • ";i.half&&parseInt(i.value)!==i.value&&u==Math.ceil(i.value)?n=n+'
  • ":n+=r}n+="
"+(i.text?''+i.value+"星":"")+"";var c=i.elem,f=c.next("."+t);f[0]&&f.remove(),e.elemTemp=a(n),i.span=e.elemTemp.next("span"),i.setText&&i.setText(i.value),c.html(e.elemTemp),c.addClass("layui-inline"),i.readonly||e.action()},v.prototype.setvalue=function(e){var a=this,i=a.config;i.value=e,a.render()},v.prototype.action=function(){var e=this,i=e.config,l=e.elemTemp,n=l.find("i").width();l.children("li").each(function(e){var t=e+1,v=a(this);v.on("click",function(e){if(i.value=t,i.half){var o=e.pageX-a(this).offset().left;o<=n/2&&(i.value=i.value-.5)}i.text&&l.next("span").text(i.value+"星"),i.choose&&i.choose(i.value),i.setText&&i.setText(i.value)}),v.on("mousemove",function(e){if(l.find("i").each(function(){a(this).addClass(o).removeClass(r)}),l.find("i:lt("+t+")").each(function(){a(this).addClass(s).removeClass(f)}),i.half){var c=e.pageX-a(this).offset().left;c<=n/2&&v.children("i").addClass(u).removeClass(s)}}),v.on("mouseleave",function(){l.find("i").each(function(){a(this).addClass(o).removeClass(r)}),l.find("i:lt("+Math.floor(i.value)+")").each(function(){a(this).addClass(s).removeClass(f)}),i.half&&parseInt(i.value)!==i.value&&l.children("li:eq("+Math.floor(i.value)+")").children("i").addClass(u).removeClass(c)})})},v.prototype.events=function(){var e=this;e.config},i.render=function(e){var a=new v(e);return l.call(a)},e(n,i)}); -------------------------------------------------------------------------------- /src/main/resources/static/layui/lay/modules/tree.js: -------------------------------------------------------------------------------- 1 | /** layui-v2.4.5 MIT License By https://www.layui.com */ 2 | ;layui.define("jquery",function(e){"use strict";var o=layui.$,a=layui.hint(),i="layui-tree-enter",r=function(e){this.options=e},t={arrow:["",""],checkbox:["",""],radio:["",""],branch:["",""],leaf:""};r.prototype.init=function(e){var o=this;e.addClass("layui-box layui-tree"),o.options.skin&&e.addClass("layui-tree-skin-"+o.options.skin),o.tree(e),o.on(e)},r.prototype.tree=function(e,a){var i=this,r=i.options,n=a||r.nodes;layui.each(n,function(a,n){var l=n.children&&n.children.length>0,c=o('
    '),s=o(["
  • ",function(){return l?''+(n.spread?t.arrow[1]:t.arrow[0])+"":""}(),function(){return r.check?''+("checkbox"===r.check?t.checkbox[0]:"radio"===r.check?t.radio[0]:"")+"":""}(),function(){return'"+(''+(l?n.spread?t.branch[1]:t.branch[0]:t.leaf)+"")+(""+(n.name||"未命名")+"")}(),"
  • "].join(""));l&&(s.append(c),i.tree(c,n.children)),e.append(s),"function"==typeof r.click&&i.click(s,n),i.spread(s,n),r.drag&&i.drag(s,n)})},r.prototype.click=function(e,o){var a=this,i=a.options;e.children("a").on("click",function(e){layui.stope(e),i.click(o)})},r.prototype.spread=function(e,o){var a=this,i=(a.options,e.children(".layui-tree-spread")),r=e.children("ul"),n=e.children("a"),l=function(){e.data("spread")?(e.data("spread",null),r.removeClass("layui-show"),i.html(t.arrow[0]),n.find(".layui-icon").html(t.branch[0])):(e.data("spread",!0),r.addClass("layui-show"),i.html(t.arrow[1]),n.find(".layui-icon").html(t.branch[1]))};r[0]&&(i.on("click",l),n.on("dblclick",l))},r.prototype.on=function(e){var a=this,r=a.options,t="layui-tree-drag";e.find("i").on("selectstart",function(e){return!1}),r.drag&&o(document).on("mousemove",function(e){var i=a.move;if(i.from){var r=(i.to,o('
    '));e.preventDefault(),o("."+t)[0]||o("body").append(r);var n=o("."+t)[0]?o("."+t):r;n.addClass("layui-show").html(i.from.elem.children("a").html()),n.css({left:e.pageX+10,top:e.pageY+10})}}).on("mouseup",function(){var e=a.move;e.from&&(e.from.elem.children("a").removeClass(i),e.to&&e.to.elem.children("a").removeClass(i),a.move={},o("."+t).remove())})},r.prototype.move={},r.prototype.drag=function(e,a){var r=this,t=(r.options,e.children("a")),n=function(){var t=o(this),n=r.move;n.from&&(n.to={item:a,elem:e},t.addClass(i))};t.on("mousedown",function(){var o=r.move;o.from={item:a,elem:e}}),t.on("mouseenter",n).on("mousemove",n).on("mouseleave",function(){var e=o(this),a=r.move;a.from&&(delete a.to,e.removeClass(i))})},e("tree",function(e){var i=new r(e=e||{}),t=o(e.elem);return t[0]?void i.init(t):a.error("layui.tree 没有找到"+e.elem+"元素")})}); -------------------------------------------------------------------------------- /src/main/resources/static/layui/lay/modules/upload.js: -------------------------------------------------------------------------------- 1 | /** layui-v2.4.5 MIT License By https://www.layui.com */ 2 | ;layui.define("layer",function(e){"use strict";var i=layui.$,t=layui.layer,n=layui.hint(),a=layui.device(),o={config:{},set:function(e){var t=this;return t.config=i.extend({},t.config,e),t},on:function(e,i){return layui.onevent.call(this,r,e,i)}},l=function(){var e=this;return{upload:function(i){e.upload.call(e,i)},config:e.config}},r="upload",u="layui-upload-file",c="layui-upload-form",f="layui-upload-iframe",s="layui-upload-choose",p=function(e){var t=this;t.config=i.extend({},t.config,o.config,e),t.render()};p.prototype.config={accept:"images",exts:"",auto:!0,bindAction:"",url:"",field:"file",method:"post",data:{},drag:!0,size:0,number:0,multiple:!1},p.prototype.render=function(e){var t=this,e=t.config;e.elem=i(e.elem),e.bindAction=i(e.bindAction),t.file(),t.events()},p.prototype.file=function(){var e=this,t=e.config,n=e.elemFile=i(['"].join("")),o=t.elem.next();(o.hasClass(u)||o.hasClass(c))&&o.remove(),a.ie&&a.ie<10&&t.elem.wrap('
    '),e.isFile()?(e.elemFile=t.elem,t.field=t.elem[0].name):t.elem.after(n),a.ie&&a.ie<10&&e.initIE()},p.prototype.initIE=function(){var e=this,t=e.config,n=i(''),a=i(['
    ',"
    "].join(""));i("#"+f)[0]||i("body").append(n),t.elem.next().hasClass(c)||(e.elemFile.wrap(a),t.elem.next("."+c).append(function(){var e=[];return layui.each(t.data,function(i,t){t="function"==typeof t?t():t,e.push('')}),e.join("")}()))},p.prototype.msg=function(e){return t.msg(e,{icon:2,shift:6})},p.prototype.isFile=function(){var e=this.config.elem[0];if(e)return"input"===e.tagName.toLocaleLowerCase()&&"file"===e.type},p.prototype.preview=function(e){var i=this;window.FileReader&&layui.each(i.chooseFiles,function(i,t){var n=new FileReader;n.readAsDataURL(t),n.onload=function(){e&&e(i,t,this.result)}})},p.prototype.upload=function(e,t){var n,o=this,l=o.config,r=o.elemFile[0],u=function(){var t=0,n=0,a=e||o.files||o.chooseFiles||r.files,u=function(){l.multiple&&t+n===o.fileLength&&"function"==typeof l.allDone&&l.allDone({total:o.fileLength,successful:t,aborted:n})};layui.each(a,function(e,a){var r=new FormData;r.append(l.field,a),layui.each(l.data,function(e,i){i="function"==typeof i?i():i,r.append(e,i)}),i.ajax({url:l.url,type:"post",data:r,contentType:!1,processData:!1,dataType:"json",headers:l.headers||{},success:function(i){t++,d(e,i),u()},error:function(){n++,o.msg("请求上传接口出现异常"),m(e),u()}})})},c=function(){var e=i("#"+f);o.elemFile.parent().submit(),clearInterval(p.timer),p.timer=setInterval(function(){var i,t=e.contents().find("body");try{i=t.text()}catch(n){o.msg("获取上传后的响应信息出现异常"),clearInterval(p.timer),m()}i&&(clearInterval(p.timer),t.html(""),d(0,i))},30)},d=function(e,i){if(o.elemFile.next("."+s).remove(),r.value="","object"!=typeof i)try{i=JSON.parse(i)}catch(t){return i={},o.msg("请对上传接口返回有效JSON")}"function"==typeof l.done&&l.done(i,e||0,function(e){o.upload(e)})},m=function(e){l.auto&&(r.value=""),"function"==typeof l.error&&l.error(e||0,function(e){o.upload(e)})},h=l.exts,v=function(){var i=[];return layui.each(e||o.chooseFiles,function(e,t){i.push(t.name)}),i}(),g={preview:function(e){o.preview(e)},upload:function(e,i){var t={};t[e]=i,o.upload(t)},pushFile:function(){return o.files=o.files||{},layui.each(o.chooseFiles,function(e,i){o.files[e]=i}),o.files},resetFile:function(e,i,t){var n=new File([i],t);o.files=o.files||{},o.files[e]=n}},y=function(){if("choose"!==t&&!l.auto||(l.choose&&l.choose(g),"choose"!==t))return l.before&&l.before(g),a.ie?a.ie>9?u():c():void u()};if(v=0===v.length?r.value.match(/[^\/\\]+\..+/g)||[]||"":v,0!==v.length){switch(l.accept){case"file":if(h&&!RegExp("\\w\\.("+h+")$","i").test(escape(v)))return o.msg("选择的文件中包含不支持的格式"),r.value="";break;case"video":if(!RegExp("\\w\\.("+(h||"avi|mp4|wma|rmvb|rm|flash|3gp|flv")+")$","i").test(escape(v)))return o.msg("选择的视频中包含不支持的格式"),r.value="";break;case"audio":if(!RegExp("\\w\\.("+(h||"mp3|wav|mid")+")$","i").test(escape(v)))return o.msg("选择的音频中包含不支持的格式"),r.value="";break;default:if(layui.each(v,function(e,i){RegExp("\\w\\.("+(h||"jpg|png|gif|bmp|jpeg$")+")","i").test(escape(i))||(n=!0)}),n)return o.msg("选择的图片中包含不支持的格式"),r.value=""}if(o.fileLength=function(){var i=0,t=e||o.files||o.chooseFiles||r.files;return layui.each(t,function(){i++}),i}(),l.number&&o.fileLength>l.number)return o.msg("同时最多只能上传的数量为:"+l.number);if(l.size>0&&!(a.ie&&a.ie<10)){var F;if(layui.each(o.chooseFiles,function(e,i){if(i.size>1024*l.size){var t=l.size/1024;t=t>=1?t.toFixed(2)+"MB":l.size+"KB",r.value="",F=t}}),F)return o.msg("文件不能超过"+F)}y()}},p.prototype.events=function(){var e=this,t=e.config,o=function(i){e.chooseFiles={},layui.each(i,function(i,t){var n=(new Date).getTime();e.chooseFiles[n+"-"+i]=t})},l=function(i,n){var a=e.elemFile,o=i.length>1?i.length+"个文件":(i[0]||{}).name||a[0].value.match(/[^\/\\]+\..+/g)||[]||"";a.next().hasClass(s)&&a.next().remove(),e.upload(null,"choose"),e.isFile()||t.choose||a.after(''+o+"")};t.elem.off("upload.start").on("upload.start",function(){var a=i(this),o=a.attr("lay-data");if(o)try{o=new Function("return "+o)(),e.config=i.extend({},t,o)}catch(l){n.error("Upload element property lay-data configuration item has a syntax error: "+o)}e.config.item=a,e.elemFile[0].click()}),a.ie&&a.ie<10||t.elem.off("upload.over").on("upload.over",function(){var e=i(this);e.attr("lay-over","")}).off("upload.leave").on("upload.leave",function(){var e=i(this);e.removeAttr("lay-over")}).off("upload.drop").on("upload.drop",function(n,a){var r=i(this),u=a.originalEvent.dataTransfer.files||[];r.removeAttr("lay-over"),o(u),t.auto?e.upload(u):l(u)}),e.elemFile.off("upload.change").on("upload.change",function(){var i=this.files||[];o(i),t.auto?e.upload():l(i)}),t.bindAction.off("upload.action").on("upload.action",function(){e.upload()}),t.elem.data("haveEvents")||(e.elemFile.on("change",function(){i(this).trigger("upload.change")}),t.elem.on("click",function(){e.isFile()||i(this).trigger("upload.start")}),t.drag&&t.elem.on("dragover",function(e){e.preventDefault(),i(this).trigger("upload.over")}).on("dragleave",function(e){i(this).trigger("upload.leave")}).on("drop",function(e){e.preventDefault(),i(this).trigger("upload.drop",e)}),t.bindAction.on("click",function(){i(this).trigger("upload.action")}),t.elem.data("haveEvents",!0))},o.render=function(e){var i=new p(e);return l.call(i)},e(r,o)}); -------------------------------------------------------------------------------- /src/main/resources/static/layui/lay/modules/util.js: -------------------------------------------------------------------------------- 1 | /** layui-v2.4.5 MIT License By https://www.layui.com */ 2 | ;layui.define("jquery",function(t){"use strict";var e=layui.$,i={fixbar:function(t){var i,a,n="layui-fixbar",r="layui-fixbar-top",o=e(document),l=e("body");t=e.extend({showHeight:200},t),t.bar1=t.bar1===!0?"":t.bar1,t.bar2=t.bar2===!0?"":t.bar2,t.bgcolor=t.bgcolor?"background-color:"+t.bgcolor:"";var c=[t.bar1,t.bar2,""],g=e(['
      ',t.bar1?'
    • '+c[0]+"
    • ":"",t.bar2?'
    • '+c[1]+"
    • ":"",'
    • '+c[2]+"
    • ","
    "].join("")),s=g.find("."+r),u=function(){var e=o.scrollTop();e>=t.showHeight?i||(s.show(),i=1):i&&(s.hide(),i=0)};e("."+n)[0]||("object"==typeof t.css&&g.css(t.css),l.append(g),u(),g.find("li").on("click",function(){var i=e(this),a=i.attr("lay-type");"top"===a&&e("html,body").animate({scrollTop:0},200),t.click&&t.click.call(this,a)}),o.on("scroll",function(){clearTimeout(a),a=setTimeout(function(){u()},100)}))},countdown:function(t,e,i){var a=this,n="function"==typeof e,r=new Date(t).getTime(),o=new Date(!e||n?(new Date).getTime():e).getTime(),l=r-o,c=[Math.floor(l/864e5),Math.floor(l/36e5)%24,Math.floor(l/6e4)%60,Math.floor(l/1e3)%60];n&&(i=e);var g=setTimeout(function(){a.countdown(t,o+1e3,i)},1e3);return i&&i(l>0?c:[0,0,0,0],e,g),l<=0&&clearTimeout(g),g},timeAgo:function(t,e){var i=this,a=[[],[]],n=(new Date).getTime()-new Date(t).getTime();return n>6912e5?(n=new Date(t),a[0][0]=i.digit(n.getFullYear(),4),a[0][1]=i.digit(n.getMonth()+1),a[0][2]=i.digit(n.getDate()),e||(a[1][0]=i.digit(n.getHours()),a[1][1]=i.digit(n.getMinutes()),a[1][2]=i.digit(n.getSeconds())),a[0].join("-")+" "+a[1].join(":")):n>=864e5?(n/1e3/60/60/24|0)+"天前":n>=36e5?(n/1e3/60/60|0)+"小时前":n>=12e4?(n/1e3/60|0)+"分钟前":n<0?"未来":"刚刚"},digit:function(t,e){var i="";t=String(t),e=e||2;for(var a=t.length;a/g,">").replace(/'/g,"'").replace(/"/g,""")}};!function(t,e,i){"$:nomunge";function a(){n=e[l](function(){r.each(function(){var e=t(this),i=e.width(),a=e.height(),n=t.data(this,g);(i!==n.w||a!==n.h)&&e.trigger(c,[n.w=i,n.h=a])}),a()},o[s])}var n,r=t([]),o=t.resize=t.extend(t.resize,{}),l="setTimeout",c="resize",g=c+"-special-event",s="delay",u="throttleWindow";o[s]=250,o[u]=!0,t.event.special[c]={setup:function(){if(!o[u]&&this[l])return!1;var e=t(this);r=r.add(e),t.data(this,g,{w:e.width(),h:e.height()}),1===r.length&&a()},teardown:function(){if(!o[u]&&this[l])return!1;var e=t(this);r=r.not(e),e.removeData(g),r.length||clearTimeout(n)},add:function(e){function a(e,a,r){var o=t(this),l=t.data(this,g)||{};l.w=a!==i?a:o.width(),l.h=r!==i?r:o.height(),n.apply(this,arguments)}if(!o[u]&&this[l])return!1;var n;return t.isFunction(e)?(n=e,a):(n=e.handler,void(e.handler=a))}}}(e,window),t("util",i)}); -------------------------------------------------------------------------------- /src/main/resources/static/layui/layui.js: -------------------------------------------------------------------------------- 1 | /** layui-v2.4.5 MIT License By https://www.layui.com */ 2 | ;!function(e){"use strict";var t=document,o={modules:{},status:{},timeout:10,event:{}},n=function(){this.v="2.4.5"},r=function(){var e=t.currentScript?t.currentScript.src:function(){for(var e,o=t.scripts,n=o.length-1,r=n;r>0;r--)if("interactive"===o[r].readyState){e=o[r].src;break}return e||o[n].src}();return e.substring(0,e.lastIndexOf("/")+1)}(),i=function(t){e.console&&console.error&&console.error("Layui hint: "+t)},a="undefined"!=typeof opera&&"[object Opera]"===opera.toString(),u={layer:"modules/layer",laydate:"modules/laydate",laypage:"modules/laypage",laytpl:"modules/laytpl",layim:"modules/layim",layedit:"modules/layedit",form:"modules/form",upload:"modules/upload",tree:"modules/tree",table:"modules/table",element:"modules/element",rate:"modules/rate",colorpicker:"modules/colorpicker",slider:"modules/slider",carousel:"modules/carousel",flow:"modules/flow",util:"modules/util",code:"modules/code",jquery:"modules/jquery",mobile:"modules/mobile","layui.all":"../layui.all"};n.prototype.cache=o,n.prototype.define=function(e,t){var n=this,r="function"==typeof e,i=function(){var e=function(e,t){layui[e]=t,o.status[e]=!0};return"function"==typeof t&&t(function(n,r){e(n,r),o.callback[n]=function(){t(e)}}),this};return r&&(t=e,e=[]),layui["layui.all"]||!layui["layui.all"]&&layui["layui.mobile"]?i.call(n):(n.use(e,i),n)},n.prototype.use=function(e,n,l){function s(e,t){var n="PLaySTATION 3"===navigator.platform?/^complete$/:/^(complete|loaded)$/;("load"===e.type||n.test((e.currentTarget||e.srcElement).readyState))&&(o.modules[f]=t,d.removeChild(v),function r(){return++m>1e3*o.timeout/4?i(f+" is not a valid module"):void(o.status[f]?c():setTimeout(r,4))}())}function c(){l.push(layui[f]),e.length>1?y.use(e.slice(1),n,l):"function"==typeof n&&n.apply(layui,l)}var y=this,p=o.dir=o.dir?o.dir:r,d=t.getElementsByTagName("head")[0];e="string"==typeof e?[e]:e,window.jQuery&&jQuery.fn.on&&(y.each(e,function(t,o){"jquery"===o&&e.splice(t,1)}),layui.jquery=layui.$=jQuery);var f=e[0],m=0;if(l=l||[],o.host=o.host||(p.match(/\/\/([\s\S]+?)\//)||["//"+location.host+"/"])[0],0===e.length||layui["layui.all"]&&u[f]||!layui["layui.all"]&&layui["layui.mobile"]&&u[f])return c(),y;if(o.modules[f])!function g(){return++m>1e3*o.timeout/4?i(f+" is not a valid module"):void("string"==typeof o.modules[f]&&o.status[f]?c():setTimeout(g,4))}();else{var v=t.createElement("script"),h=(u[f]?p+"lay/":/^\{\/\}/.test(y.modules[f])?"":o.base||"")+(y.modules[f]||f)+".js";h=h.replace(/^\{\/\}/,""),v.async=!0,v.charset="utf-8",v.src=h+function(){var e=o.version===!0?o.v||(new Date).getTime():o.version||"";return e?"?v="+e:""}(),d.appendChild(v),!v.attachEvent||v.attachEvent.toString&&v.attachEvent.toString().indexOf("[native code")<0||a?v.addEventListener("load",function(e){s(e,h)},!1):v.attachEvent("onreadystatechange",function(e){s(e,h)}),o.modules[f]=h}return y},n.prototype.getStyle=function(t,o){var n=t.currentStyle?t.currentStyle:e.getComputedStyle(t,null);return n[n.getPropertyValue?"getPropertyValue":"getAttribute"](o)},n.prototype.link=function(e,n,r){var a=this,u=t.createElement("link"),l=t.getElementsByTagName("head")[0];"string"==typeof n&&(r=n);var s=(r||e).replace(/\.|\//g,""),c=u.id="layuicss-"+s,y=0;return u.rel="stylesheet",u.href=e+(o.debug?"?v="+(new Date).getTime():""),u.media="all",t.getElementById(c)||l.appendChild(u),"function"!=typeof n?a:(function p(){return++y>1e3*o.timeout/100?i(e+" timeout"):void(1989===parseInt(a.getStyle(t.getElementById(c),"width"))?function(){n()}():setTimeout(p,100))}(),a)},o.callback={},n.prototype.factory=function(e){if(layui[e])return"function"==typeof o.callback[e]?o.callback[e]:null},n.prototype.addcss=function(e,t,n){return layui.link(o.dir+"css/"+e,t,n)},n.prototype.img=function(e,t,o){var n=new Image;return n.src=e,n.complete?t(n):(n.onload=function(){n.onload=null,"function"==typeof t&&t(n)},void(n.onerror=function(e){n.onerror=null,"function"==typeof o&&o(e)}))},n.prototype.config=function(e){e=e||{};for(var t in e)o[t]=e[t];return this},n.prototype.modules=function(){var e={};for(var t in u)e[t]=u[t];return e}(),n.prototype.extend=function(e){var t=this;e=e||{};for(var o in e)t[o]||t.modules[o]?i("模块名 "+o+" 已被占用"):t.modules[o]=e[o];return t},n.prototype.router=function(e){var t=this,e=e||location.hash,o={path:[],search:{},hash:(e.match(/[^#](#.*$)/)||[])[1]||""};return/^#\//.test(e)?(e=e.replace(/^#\//,""),o.href="/"+e,e=e.replace(/([^#])(#.*$)/,"$1").split("/")||[],t.each(e,function(e,t){/^\w+=/.test(t)?function(){t=t.split("="),o.search[t[0]]=t[1]}():o.path.push(t)}),o):o},n.prototype.data=function(t,o,n){if(t=t||"layui",n=n||localStorage,e.JSON&&e.JSON.parse){if(null===o)return delete n[t];o="object"==typeof o?o:{key:o};try{var r=JSON.parse(n[t])}catch(i){var r={}}return"value"in o&&(r[o.key]=o.value),o.remove&&delete r[o.key],n[t]=JSON.stringify(r),o.key?r[o.key]:r}},n.prototype.sessionData=function(e,t){return this.data(e,t,sessionStorage)},n.prototype.device=function(t){var o=navigator.userAgent.toLowerCase(),n=function(e){var t=new RegExp(e+"/([^\\s\\_\\-]+)");return e=(o.match(t)||[])[1],e||!1},r={os:function(){return/windows/.test(o)?"windows":/linux/.test(o)?"linux":/iphone|ipod|ipad|ios/.test(o)?"ios":/mac/.test(o)?"mac":void 0}(),ie:function(){return!!(e.ActiveXObject||"ActiveXObject"in e)&&((o.match(/msie\s(\d+)/)||[])[1]||"11")}(),weixin:n("micromessenger")};return t&&!r[t]&&(r[t]=n(t)),r.android=/android/.test(o),r.ios="ios"===r.os,r},n.prototype.hint=function(){return{error:i}},n.prototype.each=function(e,t){var o,n=this;if("function"!=typeof t)return n;if(e=e||[],e.constructor===Object){for(o in e)if(t.call(e[o],o,e[o]))break}else for(o=0;oi?1:r 3 | 4 | 5 | 6 | 404 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
    15 | 16 |

    17 |
    18 |
    19 | 20 | 23 | 24 | -------------------------------------------------------------------------------- /src/main/resources/templates/error/5xx.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 404 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
    15 | 16 |

    17 |
    18 |
    19 | 20 | 23 | 24 | -------------------------------------------------------------------------------- /src/main/resources/templates/preview.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 预览 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 |
    21 | 22 |
    23 |
    24 | 25 | 34 |
    35 | 36 |
    37 | 38 |
    39 | 40 |
    41 | [[${content.contentText}]] 42 |
    43 |
    44 | [[${time}]] 45 | [[${content.likeCount}]] 46 | [[${content.hateCount}]] 47 | [[${content.shareCount}]] 48 |
    49 | 50 | 51 |
    52 |
    53 | 54 |
    [[${forum.name}]]
    55 |
    56 |
    57 |
    58 |
    59 | 60 | 61 |
    62 |
    热门评论
    63 |
    64 | 65 |
    [[${comment.nickname}]]
    66 |
    [[${comment.comment_text}]]
    67 |
    68 |
    69 |
    70 | 71 |
    72 | 73 | -------------------------------------------------------------------------------- /src/main/resources/trigger.txt: -------------------------------------------------------------------------------- 1 | version=13 -------------------------------------------------------------------------------- /src/test/java/com/xmlvhy/crawler/CrawlerBsbdjApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.xmlvhy.crawler; 2 | 3 | import com.xmlvhy.crawler.service.DataProcessedService; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | import org.springframework.test.context.junit4.SpringRunner; 9 | 10 | @RunWith(SpringRunner.class) 11 | @SpringBootTest 12 | public class CrawlerBsbdjApplicationTests { 13 | 14 | @Autowired 15 | private DataProcessedService dataProcessedService; 16 | 17 | @Test 18 | public void contextLoads() { 19 | //解析 20 | dataProcessedService.sourceDataEtl(); 21 | } 22 | 23 | } 24 | --------------------------------------------------------------------------------