今日学习(自律天数:10 11) 这2天把项目敲得差不多了 给大家简单介绍一下

162 阅读2分钟

前言

昨天没发是一直在写项目,想逻辑。

大概是一个小说爬取网,能动态编写小说源来爬取。现在已经是实现了爬取逻辑,还进行了多线程优化。

1. 爬取不同源小说同时进行

没一个小说源大概得给我这个页面的解析 image.png

这个方法是哪一个url 什么规则 分页爬取

getBookInfoList(crawlerWebTypeUrl.getUrl(), rule.getCategory(), 1, 2);

在只需要加个线程池把这个任务扔进去就完成了第一层不同源

2. 二层优化

拿到以上那个图片中的小说集合 可以进行分段

public static <T> List<List<T>> divideList(List<T> originalList, int numberOfChunks) {  
List<List<T>> dividedList = new ArrayList<>();  
  
int chunkSize = (int) Math.ceil((double) originalList.size() / numberOfChunks);  
int index = 0;  
  
for (int i = 0; i < numberOfChunks; i++) {  
if (index >= originalList.size()) {  
break;  
}  
  
List<T> chunk = originalList.subList(index, Math.min(index + chunkSize, originalList.size()));  
dividedList.add(chunk);  
index += chunkSize;  
}  
 
return dividedList;  
}

3. 为每一个小说是否分章爬取

image.png

把图片中的所有章节获取 这里也可以分章节爬取 如分2个线程 那么一个线程负责一半嘛

在章节获取时还可以优化比如 每个线程是批量上传的如爬取100个小说后再进行插入数据库操作。

批量上传这里就有个问题,数据库id怎么办我采用的是批量拉取id

@Override  //通过乐观锁
public BookChapterIdVO getId(int size) {  
BookChapterId bookChapterId = bookChapterIdMapper.selectById(1);  
  
while (bookChapterIdMapper.update(null, Wrappers.lambdaUpdate(BookChapterId.class)  
.set(BookChapterId::getVersion, bookChapterId.getVersion() + 1)  
.set(BookChapterId::getBookChapterId, bookChapterId.getBookChapterId() + size)  
.eq(BookChapterId::getVersion, bookChapterId.getVersion())  
.eq(BookChapterId::getId, bookChapterId.getId())  
) != 1) {  
bookChapterId = bookChapterIdMapper.selectById(1);  
}  
  
return new BookChapterIdVO(bookChapterId.getBookChapterId(), bookChapterId.getBookChapterId() + size);  
}

这是数据库 image.png

通过乐观锁的机制多线程安全获取ID批量拉取

4. 自己的思考

如何进行文章更新,可以写一个定时任务在每天12点的时候拉取所有正在连载的小说,去爬取这个连载小说的最新章节是否在小说库中,直到获取章节存在为止。

还可以进行分库分表优化爬取小说

以上运用的线程模型大概是 n个数据源---m个小说段---k个小说章节