feat: 增加爬虫案例
This commit is contained in:
20
pom.xml
20
pom.xml
@@ -21,6 +21,7 @@
|
||||
|
||||
<hutool.version>5.8.39</hutool.version>
|
||||
<liteflow.version>2.15.0</liteflow.version>
|
||||
<selenium.version>4.38.1</selenium.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
@@ -44,15 +45,26 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-core</artifactId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>${hutool.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-ai</artifactId>
|
||||
<version>${hutool.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.yomahub</groupId>
|
||||
<artifactId>liteflow-spring-boot-starter</artifactId>
|
||||
<version>${liteflow.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.seleniumhq.selenium</groupId>
|
||||
<artifactId>selenium-java</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
@@ -82,6 +94,12 @@
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.seleniumhq.selenium</groupId>
|
||||
<artifactId>selenium-dependencies-bom</artifactId>
|
||||
<version>${selenium.version}</version>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ public class Book extends SimpleEntity {
|
||||
@Column(nullable = false)
|
||||
private String name;
|
||||
private String author;
|
||||
@Column(columnDefinition = "text")
|
||||
private String description;
|
||||
private String source;
|
||||
@ElementCollection(fetch = FetchType.EAGER)
|
||||
|
||||
@@ -40,7 +40,6 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
||||
public class Chapter extends SimpleEntity {
|
||||
@Column(nullable = false)
|
||||
private Double sequence;
|
||||
@Column(nullable = false)
|
||||
private String name;
|
||||
private String description;
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.lanyuanxiaoyao.bookstore.service;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 书籍下载
|
||||
*
|
||||
* @author lanyuanxiaoyao
|
||||
* @version 20251031
|
||||
*/
|
||||
@Service
|
||||
public class CrawlerService {
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
package com.lanyuanxiaoyao.bookstore;
|
||||
|
||||
import cn.hutool.core.thread.ThreadUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.openqa.selenium.By;
|
||||
import org.openqa.selenium.chrome.ChromeDriver;
|
||||
import org.openqa.selenium.chrome.ChromeDriverService;
|
||||
import org.openqa.selenium.chrome.ChromeOptions;
|
||||
|
||||
/**
|
||||
* @author lanyuanxiaoyao
|
||||
* @version 20251031
|
||||
*/
|
||||
@Slf4j
|
||||
public class BookCrawlerTest {
|
||||
public static void main(String[] args) throws IOException {
|
||||
ChromeDriver driver = null;
|
||||
try {
|
||||
driver = new ChromeDriver(
|
||||
new ChromeDriverService.Builder()
|
||||
.usingDriverExecutable(new File("/Users/lanyuanxiaoyao/Downloads/chromium/134/macOS-1345775/chromedriver"))
|
||||
.build(),
|
||||
new ChromeOptions()
|
||||
.setBinary(new File("/Users/lanyuanxiaoyao/Downloads/chromium/134/macOS-1345775/Chromium.app/Contents/MacOS/Chromium"))
|
||||
.addArguments(
|
||||
// 允许不安全的域名
|
||||
"--allow-insecure-localhost",
|
||||
// 禁用GPU渲染,headLess 模式用不上
|
||||
"--disable-gpu",
|
||||
// 禁用音频输出
|
||||
"--disable-audio-output",
|
||||
// 禁用错误页自动重新刷新
|
||||
"--disable-auto-reload",
|
||||
// 禁用默认应用加载
|
||||
"--disable-default-apps",
|
||||
// 禁用浏览器扩展
|
||||
"--disable-extensions",
|
||||
// 禁用日志
|
||||
"--disable-logging",
|
||||
// 禁用通知
|
||||
"--disable-notifications",
|
||||
// 禁用远程字体
|
||||
"--disable-remote-fonts",
|
||||
// 禁用弹出窗口
|
||||
"--disable-popup-blocking",
|
||||
// 禁用同步
|
||||
"--disable-sync",
|
||||
// 禁用沙盒
|
||||
"--no-sandbox",
|
||||
// 禁用声音
|
||||
"--mute-audio",
|
||||
// 禁止图片显示
|
||||
"blink-settings=imagesEnabled=false"
|
||||
)
|
||||
);
|
||||
var articleUrl = "https://www.alicesw.com/novel/33927.html";
|
||||
driver.get(articleUrl);
|
||||
var contextUrl = driver.findElement(By.xpath("//div[@class='book_newchap']//a[contains(text(),'查看所有章节')]")).getDomProperty("href");
|
||||
if (StrUtil.isBlank(contextUrl)) {
|
||||
throw new RuntimeException("获取目录页链接失败");
|
||||
}
|
||||
driver.get(contextUrl);
|
||||
var chapterItems = driver.findElements(By.cssSelector("ul.mulu_list > li > a"))
|
||||
.stream()
|
||||
.map(element -> element.getDomProperty("href"))
|
||||
.toList();
|
||||
for (var index = 0; index < chapterItems.size(); index++) {
|
||||
var chapterUrl = chapterItems.get(index);
|
||||
if (StrUtil.isBlank(chapterUrl)) {
|
||||
throw new RuntimeException("获取章节链接失败: " + chapterUrl);
|
||||
}
|
||||
driver.get(chapterUrl);
|
||||
var text = driver.findElement(By.cssSelector(".read-content")).getText();
|
||||
log.info(text);
|
||||
|
||||
var title = driver.getTitle();
|
||||
if (StrUtil.isBlank(title)) {
|
||||
title = String.valueOf(index);
|
||||
}
|
||||
var filename = StrUtil.format("{}.txt", title.replaceAll("\\s", "_"));
|
||||
var targetFile = Path.of("out", filename);
|
||||
Files.deleteIfExists(targetFile);
|
||||
Files.createFile(targetFile);
|
||||
Files.writeString(targetFile, text);
|
||||
|
||||
ThreadUtil.safeSleep(5000);
|
||||
}
|
||||
} finally {
|
||||
if (driver != null) {
|
||||
driver.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
package com.lanyuanxiaoyao.bookstore;
|
||||
|
||||
import cn.hutool.ai.AIUtil;
|
||||
import cn.hutool.ai.ModelName;
|
||||
import cn.hutool.ai.core.AIConfigBuilder;
|
||||
import java.io.IOException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 更新章节
|
||||
*
|
||||
* @author lanyuanxiaoyao
|
||||
* @version 20251031
|
||||
*/
|
||||
@Slf4j
|
||||
public class UpdateIntoDatabase {
|
||||
public static void main(String[] args) throws IOException {
|
||||
/*var chapters = new ArrayList<Chapter>();
|
||||
Files.list(Path.of("out"))
|
||||
.sorted(Comparator.comparing(path -> FileUtil.lastModifiedTime(path.toFile())))
|
||||
.forEach(path -> {
|
||||
try {
|
||||
chapters.add(new Chapter(
|
||||
path.getFileName().toString(),
|
||||
Files.readString(path)
|
||||
));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
for (var chapter : chapters) {
|
||||
log.info("name: {}", chapter.title());
|
||||
}*/
|
||||
var response = AIUtil.chat(
|
||||
new AIConfigBuilder(ModelName.OPENAI.getValue())
|
||||
.setApiUrl("http://127.0.0.1:30000")
|
||||
.setApiKey("*XMySqV%>hR&v>>g*NwCs3tpQ5FVMFEF2VHVTj<MYQd$&@$sY7CgqNyea4giJi4")
|
||||
.setModel("")
|
||||
.setTimout(1000 * 60 * 5)
|
||||
.build(),
|
||||
"""
|
||||
丹枫的视线垂下,脸颊渐红。
|
||||
衣裳从微粉的肩上滑落,丰腴袅娜的娇躯顿时暴露在空气中。丰满圆润的乳峰顶上,两颗深粉色的乳尖渐渐勃起,凝脂般的肌肤在光线下泛起些许象牙般的光泽。
|
||||
两条白臂时而遮住平坦的小腹,时而在胸前与腰侧间徘徊,一副局促模样。
|
||||
与玉霜坦诚相见并不足以令她这般羞耻,只是一想到两人接下来要做的事情,本就被花雾影响的身躯更加火热,一道热血直冲脑门难以散去,为脖颈与耳朵也添了一抹赤色。
|
||||
玉霜伸手拉开腰间的系带,褶衣与裳柔顺丝滑地与身躯分离,将光滑的美背与丰满的臀肉暴露在了身后丹枫的眼离。
|
||||
她的身躯曲线格外柔美,是令丹枫为之羡慕的完美比例,饱满挺拔 的乳峰顶点缀着两朵粉红樱兔,紧致纤细的腰肢上隐约可见肌肉的线条,高高翘起的臀肉顶端泛着细腻的光泽,缝隙深处的馥郁之中正渗出些许体液。
|
||||
面对飞星的身体,她的娇躯自然发情,在花雾的影响下,快速流动的血液令雪颊泛起一层淡淡的胭脂色,但她的神情仍然像往常一样清冷淡漠,只有眼里闪烁着柔软的担忧。
|
||||
此次飞星对秋音君使用能力之后,在极其疲惫的状态下仍然强行将效果延长,此时受到的反噬也要比之前更为剧烈。
|
||||
强烈的欲望使得飞星无法入眠,却也发不出声音,更没有动弹的力气。
|
||||
他的眼睛微微睁着,脑海中一片混沌,但又保留了些许意识,令他能清醒地承受这份折磨。
|
||||
她是第一次见到飞星这种状态,哪怕身体已经准备好了,内心也无法安心地享受鱼水之欢。
|
||||
此刻他这般虚弱,又需要排解欲望,那便只能由她们来主动了。
|
||||
丹枫走到床边,看着他这模样也自然心疼起来,俯下身子,取出块洁净的丝布擦了擦他脸上的汗水。
|
||||
两人一起上了床。
|
||||
丹枫侧身跪坐着,将双腿垫在飞星的头下,俯下身去轻吻他的嘴唇。
|
||||
她伸出舌头,反复舔舐着他的嘴唇,而后轻柔地滑入他的口中,将嘴里含着的丹药与仙露缓缓渡给他。
|
||||
仙露与丹药入喉,丹枫身上淡淡的香甜气息随之飘入飞星的鼻腔,飞星的眼珠微微颤动。
|
||||
“很快就没事了~”
|
||||
耳边响起她那慈爱而宠溺的传音。
|
||||
“啵嗞~嗞~”
|
||||
她用舌头包裹住他的舌尖,轻轻吮吸起来,与他对视着,桃眸泛着水光,荡漾着对他的怜爱。一只手捧着他的脸颊,一只手柔柔地抚摸他的脑袋,还从储物空间中取出一块南海冰霜,飘浮在床边为他降温。
|
||||
玉霜将飞星的双腿分开,趴在他的双腿间,解开了他的衣裳,坚硬的龙身上青筋暴起,龙头昂首向上。
|
||||
纤纤玉指将两鬓的发丝拂到耳后,她伸手握住一弹一弹颤动着的阳物,随后俯下头去——
|
||||
飞星只感到下体进入了一个极为湿润且温暖的腔中,与阴穴不同,那腔中有一抹更为柔软且灵活的东西,从深处传来了一阵阵吸力,龙头顿时感到一抹酥爽的快感。
|
||||
只见玉霜一手扶着飞星的大腿根部,一手握在龙根处,将飞星的阳物吞入口中。
|
||||
为了容纳他的阳物,她那一张樱桃小嘴张得极大,双颊随之凹缩了一些,舌根咽喉处则因此鼓起。
|
||||
身为修仙者,与她们一样,飞星的下身也没有异味。玉霜嗅着他的淡淡体味,双唇用力紧缩,避免牙齿碰到那敏感的龙头,将阳根连同唾液一同吞吐着,发出啧嗞啧嗞的水声。
|
||||
虽然她的动作还不熟练,但是此刻被花雾所影响的飞星的身体极为敏感,阵阵快感从下身传来,只十几息后,他的身躯便紧绷起来。
|
||||
玉霜见状,大幅度吞吐几下,而后猛地埋下头去,使阳根插至自己的喉咙深处。
|
||||
只见飞星的腰臀不受控制地颤抖几下,一道道精液随之灌入玉霜的食道,径直落入她的腹中。
|
||||
“嗯~”
|
||||
她闷哼一声,呼吸受阻,眉头微微蹙起,感受着喉咙里的阳根不断抽动。
|
||||
不知是不是丹药已经生效了,飞星的意识清晰了不少,努力将嘴角扬起,朝面前的丹枫微微一笑。
|
||||
丹枫见状,脸上也随之泛起一抹笑容来,又在他额前一吻。
|
||||
待飞星高潮完后,玉霜才将阳物吐出,把头靠在飞星的腿根,伸手扶着阳物贴在自己的脸颊上,看向飞星问道:
|
||||
“好些了吗?”
|
||||
“嗯……”飞星轻嗯一声,但似乎还是没有说话的力气,也无法有其他动作。
|
||||
覆盖他全身肌肤的赤红并未褪去,阳物也依旧坚挺,看来只一次是完全不够的。
|
||||
玉霜侧过去头去,朝龙身亲了一下。
|
||||
“啵~”
|
||||
她将人中贴在阳物下方,温热的鼻息打在龙头上,阳物轻轻一颤,从龙口淌出一些残余的元精。
|
||||
她伸出舌头,舔过龙口,将残精卷入口中,而后樱唇一张,轻轻吮吸着龙头。
|
||||
丹枫俯下身去,将头埋在他的胸口,伸出舌头舔弄起他的乳首,同时捧着自己的乳峰,将自己那颗勃起许久的乳尖递到了飞星的嘴边。
|
||||
飞星自然张口将嫣红的樱桃含入口中,与丹枫一同舔舐着对方的乳头。
|
||||
玉霜将舌尖抵在龙口处不停舔舐,亲吻几下后,又伸长舌头在龙根与春袋的交界处滑动着向上舔去,直至抵住龙口处的系带,而后再度将龙根吞入口中,伴随脑袋的前后摆动吞吐起来。
|
||||
“咕嗞~卟嗞~”
|
||||
阵阵快感再度袭来,飞星的呼吸很快又重了起来。
|
||||
丹枫感受到他的头部正在迅速升温,坐起身来,将南海冰霜垫到了他的脑下,随后也来到了他的下身。
|
||||
玉霜看了她一眼,将阳物吐出。
|
||||
唾液从她的唇角落下,显得有些魅惑。
|
||||
她来到飞星上身,将位置让给丹枫,而后从储物空间中取出些仙露滴在掌心上,伸手在飞星的胸口涂抹起来。
|
||||
丹枫接替了玉霜的位置,俯下头去,将飞星的春袋含入口中,轻柔地吮吸几下后,再吐出,舌尖紧紧贴着龙身,在龙根与龙口间不停上下滑动。
|
||||
而后,她伸出双手食指,落在龙口两旁,轻轻按下,向两边掰开,露出一点泛着光泽的嫩肉来,舌尖深入龙口内的敏感之中如细小的游鱼般抖动着舔舐起来。
|
||||
“嗯……”飞星微微一颤。
|
||||
丹枫见状用玉指箍住冠沟,在龙头处大幅度上下舔动起来。
|
||||
玉霜俯下身来,将两团乳峰靠近飞星的脸部,用柔软的乳肉包裹着飞星的双颊。
|
||||
阵阵快感令飞星低吟不断,他的身躯渐渐紧绷,丹枫抬眼看着飞星的神情,双手一同捏在阳物根部,将阳物没入口中吞吐起来,口中的香舌紧紧缠绕着龙头,与箍紧的嘴唇一同刺激着龙头。
|
||||
强烈的快感下,飞星的精关失守,伴随下身的阵阵抽动,道道元精爆发在丹枫的口中。
|
||||
“咕嘟~咕嘟~”
|
||||
她不停将元精吞下,伴随缓慢的起身,阳根也从她口中缓缓退出。
|
||||
她的红唇紧紧箍着阳根,脖颈后仰,龙头渐渐从她嘴中退出,而后在即将离开红唇的时候,她将舌尖抵到唇口的龙口上,紧紧吸住阳物的顶端,用力吮吸着,仿佛要将最后一点元精也榨出来。
|
||||
“嗞嗞哫~嗞哫~啧嗞~~”
|
||||
“嗯……!”
|
||||
飞星闷哼一声,眉头皱起,下身刚刚才高潮过后下身本就敏感无比,此刻似乎又有什么东西正不受控制地要涌出来。
|
||||
只见丹枫伸手握住他的阳根,一边撸动着,一边将龙头重新塞入口中,快速吮吸起来。
|
||||
玉霜抱着他的脑袋,将乳尖塞入他的口中,轻声说道:“射出来吧~”
|
||||
飞星一阵颤抖,只感到下身几乎要融化,而后又是一股元精涌出——
|
||||
丹枫张大了檀口,伸着舌头接着,元精大多射入了她的口中,一部分打在她的脸上,还有一部分落在她那丰满的乳肉上。
|
||||
“呼……呼……”
|
||||
飞星喘着粗气,阳物仍然坚挺。
|
||||
在花雾的影响下,丹枫与玉霜的双颊也已潮红。
|
||||
丹枫伸手拂过脸颊上的元精塞入口中,同时坐起身来,横跨在飞星的双腿上。
|
||||
两瓣阴唇已开,粉嫩的穴肉间已经流下了一道道阴液,她喘着气,眸中流露出几丝难耐的爱欲。
|
||||
“师姐,那我先——”
|
||||
她伸手握着飞星的阳物,对准了自己的穴口,俯下腰去——
|
||||
阳物挤开湿润紧致的穴肉,深入腔穴,抵在了胞宫口上。
|
||||
“啊~”
|
||||
她仰头低吟一声,感受到下身的充实,满足地长舒一口气。
|
||||
只见她的腰身缓缓前后摇动起来,丰满的乳肉开始晃荡,口中的娇吟渐渐频繁。
|
||||
“啊~嗯~”
|
||||
玉霜盯着两人的交合处,眉头不自觉地蹙起,轻咬着下唇,眼中流露出几丝羡慕,腔穴一缩,便淌出了一道阴液。
|
||||
飞星看着她,手指微微一动。
|
||||
玉霜明白他的意思,轻声道:
|
||||
“你的体力还没恢复,不用勉强。”
|
||||
飞星想了想,张开嘴,伸出了舌头。
|
||||
玉霜脸颊欲红,低声道:
|
||||
“明明你都这样了,我还……”
|
||||
她说着,起身横跨在飞星的脖颈处,将已经泛滥的粉嫩下阴凑到了飞星的下颌处。
|
||||
她羞声道:
|
||||
“但我实在也有点忍不住了……”
|
||||
飞星朝她微微一笑,伸出舌头舔上她的下阴。
|
||||
“啊~~”
|
||||
……
|
||||
此刻的屋外。
|
||||
日洒青石,风动翠枝。
|
||||
广刹看向庭院中的试剑石,心中有些怀念。
|
||||
院里一片安宁,整座福栖殿都安静无比。
|
||||
她一间间屋子巡视过来,并未感知到任何动静。
|
||||
只剩下最后一间了。
|
||||
她看向那间屋子。
|
||||
是玉霜师姐的屋子。
|
||||
广刹来到门前,神色微微一变。
|
||||
她感知到里面有人,但是却没听到任何声音。
|
||||
隔音禁制?
|
||||
可师姐这个时候不应该在落尘溪吗?
|
||||
她眉头皱起,犹豫片刻后,伸手一推,破门而入——
|
||||
……
|
||||
|
||||
—————
|
||||
上述是小说一个章节的内容,需要你为章节拟2句金庸武侠风格的七言绝句作为章节标题,标题在精确概括章节内容外也需要充满文学性、浪漫性,直接输出标题文字,除了标题外严禁输出任何无关的文字,禁止输出任何markdown格式
|
||||
"""
|
||||
);
|
||||
log.info("response: {}", response);
|
||||
}
|
||||
|
||||
public record Chapter(String title, String content) {
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user