aaaaaaaaa
This commit is contained in:
parent
b80852e7a0
commit
f6cedc1a37
|
@ -1,6 +1,8 @@
|
||||||
package com.dengqn.app.lingyinapi.apis;
|
package com.dengqn.app.lingyinapi.apis;
|
||||||
|
|
||||||
import com.dengqn.app.lingyinapi.beans.SeedListItem;
|
import com.dengqn.app.lingyinapi.beans.SeedListItem;
|
||||||
|
import com.dengqn.app.lingyinapi.beans.api.Page;
|
||||||
|
import com.dengqn.app.lingyinapi.beans.api.Resp;
|
||||||
import com.dengqn.app.lingyinapi.config.CookieConfig;
|
import com.dengqn.app.lingyinapi.config.CookieConfig;
|
||||||
import com.dengqn.app.lingyinapi.html.HtmlTool;
|
import com.dengqn.app.lingyinapi.html.HtmlTool;
|
||||||
import com.dengqn.app.lingyinapi.http.HttpTool;
|
import com.dengqn.app.lingyinapi.http.HttpTool;
|
||||||
|
@ -40,20 +42,27 @@ public class Seed {
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/list")
|
@GetMapping("/list")
|
||||||
public ResponseEntity<List<SeedListItem>> getSeedPage(
|
public ResponseEntity<Resp<Page<SeedListItem>>> getSeedPage(
|
||||||
@RequestParam(required = false, defaultValue = "0", name = "inclbookmarked") String inclbookmarked,
|
@RequestParam(required = false, defaultValue = "0", name = "inclbookmarked") String inclbookmarked,
|
||||||
@RequestParam(required = false, defaultValue = "1", name = "incldead") String incldead,
|
@RequestParam(required = false, defaultValue = "1", name = "incldead") String incldead,
|
||||||
@RequestParam(required = false, defaultValue = "0", name = "spstate") String spstate,
|
@RequestParam(required = false, defaultValue = "0", name = "spstate") String spstate,
|
||||||
@RequestParam(required = false, defaultValue = "1", name = "page") String page
|
@RequestParam(required = false, defaultValue = "0", name = "page") String page,
|
||||||
|
@RequestParam(required = false, defaultValue = "50", name = "size") String size,
|
||||||
|
@RequestParam(required = false, defaultValue = "", name = "search") String search
|
||||||
) throws IOException {
|
) throws IOException {
|
||||||
|
String url = "https://pt.soulvoice.club/special.php?inclbookmarked=%s&incldead=%s&spstate=%s&page=%s&search=%s"
|
||||||
String url = "https://pt.soulvoice.club/special.php?inclbookmarked=%s&incldead=%s&spstate=%s&page=%s"
|
.formatted(inclbookmarked, incldead, spstate, page, search);
|
||||||
.formatted(inclbookmarked, incldead, spstate, page);
|
|
||||||
String html = HttpTool.getHTML(url, okHttpClient);
|
String html = HttpTool.getHTML(url, okHttpClient);
|
||||||
log.info("html:{}", html);
|
log.info("html:{}", html);
|
||||||
Document doc = Jsoup.parse(html);
|
Document doc = Jsoup.parse(html);
|
||||||
List<SeedListItem> listItem = HtmlTool.getSeedListItem(doc);
|
List<SeedListItem> listItem = HtmlTool.getSeedListItem(doc);
|
||||||
return ResponseEntity.ok(listItem);
|
return ResponseEntity.ok(
|
||||||
|
Resp.ok(Page.<SeedListItem>builder()
|
||||||
|
.page(Integer.valueOf(page))
|
||||||
|
.size(Integer.valueOf(size))
|
||||||
|
.total(HtmlTool.getPageTotal(doc))
|
||||||
|
.list(listItem)
|
||||||
|
.build()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,11 @@ package com.dengqn.app.lingyinapi.beans;
|
||||||
* @author dengqn
|
* @author dengqn
|
||||||
* @since 2025/9/25 18:22
|
* @since 2025/9/25 18:22
|
||||||
*/
|
*/
|
||||||
public record SeedListItem(String seedCover, String seedName, String seedUrl, boolean isFree, boolean isHitAndRun,
|
public record SeedListItem(String seedCover,
|
||||||
|
String seedName,
|
||||||
|
String seedUrl,
|
||||||
|
String seedDesc,
|
||||||
|
boolean isFree, boolean isHitAndRun,
|
||||||
String downloadUrl, String time, String size, String seeders, String views,
|
String downloadUrl, String time, String size, String seeders, String views,
|
||||||
boolean isAnonymous) {
|
boolean isAnonymous) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.dengqn.app.lingyinapi.beans.api;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页
|
||||||
|
*
|
||||||
|
* @author dengqn
|
||||||
|
* @since 2025/9/26 10:28
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Builder
|
||||||
|
@Data
|
||||||
|
public class Page<T> implements Serializable {
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 7287992347791111742L;
|
||||||
|
private Integer page;
|
||||||
|
private Integer size;
|
||||||
|
private Integer total;
|
||||||
|
private List<T> list;
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
package com.dengqn.app.lingyinapi.beans.api;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author dengqn
|
||||||
|
* @since 2025/9/26 10:19
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class Resp<T> implements Serializable {
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 3854320483518994111L;
|
||||||
|
|
||||||
|
private Integer code;
|
||||||
|
|
||||||
|
private String msg;
|
||||||
|
|
||||||
|
private T data;
|
||||||
|
|
||||||
|
public static <T> Resp<T> ok(T data) {
|
||||||
|
return ok("ok", data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Resp<T> ok(String msg, T data) {
|
||||||
|
return Resp.<T>builder()
|
||||||
|
.code(10000)
|
||||||
|
.msg(msg)
|
||||||
|
.data(data)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Resp<T> error(String msg) {
|
||||||
|
return Resp.<T>builder()
|
||||||
|
.code(10001)
|
||||||
|
.msg(msg)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Resp<T> error(Integer code, String msg) {
|
||||||
|
return Resp.<T>builder()
|
||||||
|
.code(code)
|
||||||
|
.msg(msg)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,17 +18,15 @@ import java.util.Objects;
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class HtmlTool {
|
public class HtmlTool {
|
||||||
public static List<SeedListItem> getSeedListItem(Document doc) {
|
public static List<SeedListItem> getSeedListItem(Document doc) {
|
||||||
List<SeedListItem> items = new ArrayList<>();
|
|
||||||
|
|
||||||
Element torrents;
|
Element torrents;
|
||||||
try {
|
try {
|
||||||
torrents = doc.getElementsByClass("torrents").getFirst();
|
torrents = doc.getElementsByClass("torrents").getFirst();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.info("搜不到东西:{}", e.getMessage());
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
return torrents.select("tr").stream().skip(1)
|
return torrents.select("tr").parallelStream().skip(1)
|
||||||
.map(tr -> {
|
.map(tr -> {
|
||||||
try {
|
try {
|
||||||
/**
|
/**
|
||||||
|
@ -39,6 +37,7 @@ public class HtmlTool {
|
||||||
String seedCover = seedNames.get(0).getElementsByTag("img").first().attr("data-src");
|
String seedCover = seedNames.get(0).getElementsByTag("img").first().attr("data-src");
|
||||||
String seedName = seedNames.get(1).getElementsByTag("a").first().attr("title");
|
String seedName = seedNames.get(1).getElementsByTag("a").first().attr("title");
|
||||||
String seedUrl = seedNames.get(1).getElementsByTag("a").first().attr("href");
|
String seedUrl = seedNames.get(1).getElementsByTag("a").first().attr("href");
|
||||||
|
String seedDesc = seedNames.text().replaceFirst(seedName, "");
|
||||||
boolean isFree = seedNames.get(1).getElementsByClass("pro_free").size() > 0;
|
boolean isFree = seedNames.get(1).getElementsByClass("pro_free").size() > 0;
|
||||||
boolean isHitAndRun = seedNames.get(1).getElementsByClass("hitandrun").size() > 0;
|
boolean isHitAndRun = seedNames.get(1).getElementsByClass("hitandrun").size() > 0;
|
||||||
String downloadUrl = seedNames.get(3).getElementsByTag("a").first().attr("href");
|
String downloadUrl = seedNames.get(3).getElementsByTag("a").first().attr("href");
|
||||||
|
@ -54,12 +53,27 @@ public class HtmlTool {
|
||||||
String views = tds.get(7).getElementsByTag("b") == null || tds.get(7).getElementsByTag("b").size() == 0 ? "0" : tds.get(7).getElementsByTag("b").first().text().trim();
|
String views = tds.get(7).getElementsByTag("b") == null || tds.get(7).getElementsByTag("b").size() == 0 ? "0" : tds.get(7).getElementsByTag("b").first().text().trim();
|
||||||
boolean isAnonymous = tds.get(8).text().trim().contains("匿名");
|
boolean isAnonymous = tds.get(8).text().trim().contains("匿名");
|
||||||
|
|
||||||
|
return new SeedListItem(seedCover, seedName, seedUrl, seedDesc, isFree, isHitAndRun, downloadUrl, time, size, seeders, views, isAnonymous);
|
||||||
return new SeedListItem(seedCover, seedName, seedUrl, isFree, isHitAndRun, downloadUrl, time, size, seeders, views, isAnonymous);
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("解析报错跳过:" + e.getMessage());
|
log.error("解析报错跳过:" + e.getMessage());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}).filter(Objects::nonNull).toList();
|
}).filter(Objects::nonNull).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Integer getPageTotal(Document document) {
|
||||||
|
Elements paginationEl = document.getElementsByClass("nexus-pagination");
|
||||||
|
if (paginationEl == null) return 0;
|
||||||
|
|
||||||
|
Elements pages = paginationEl.first().getElementsByTag("a");
|
||||||
|
if (pages == null || pages.size() == 0) return 0;
|
||||||
|
|
||||||
|
Element lastA = pages.last();
|
||||||
|
String text = lastA.text();
|
||||||
|
if ("".equalsIgnoreCase(text.trim())) return 0;
|
||||||
|
return Integer.valueOf(text.trim()
|
||||||
|
.replaceAll("\"", "")
|
||||||
|
.replaceAll(" ", "")
|
||||||
|
.split("-")[1]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ public class HttpTool {
|
||||||
try {
|
try {
|
||||||
Response response = okHttpClient.newCall(new Request.Builder()
|
Response response = okHttpClient.newCall(new Request.Builder()
|
||||||
.url(url)
|
.url(url)
|
||||||
|
.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36")
|
||||||
.method("GET", null)
|
.method("GET", null)
|
||||||
.build())
|
.build())
|
||||||
.execute();
|
.execute();
|
||||||
|
|
|
@ -580,7 +580,8 @@
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</form>
|
</form>
|
||||||
<p align="center" class='nexus-pagination'><a href="?inclbookmarked=0&incldead=1&spstate=0&page=0"><b
|
<p align="center" class='nexus-pagination'>
|
||||||
|
<a href="?inclbookmarked=0&incldead=1&spstate=0&page=0"><b
|
||||||
title="Alt+Pageup"><< 上一页</b></a> <a
|
title="Alt+Pageup"><< 上一页</b></a> <a
|
||||||
href="?inclbookmarked=0&incldead=1&spstate=0&page=2"><b
|
href="?inclbookmarked=0&incldead=1&spstate=0&page=2"><b
|
||||||
title="Alt+Pagedown">下一页 >></b></a><br/><a
|
title="Alt+Pagedown">下一页 >></b></a><br/><a
|
||||||
|
@ -590,7 +591,8 @@
|
||||||
href="?inclbookmarked=0&incldead=1&spstate=0&page=3"><b>151 - 200</b></a> | ... | <a
|
href="?inclbookmarked=0&incldead=1&spstate=0&page=3"><b>151 - 200</b></a> | ... | <a
|
||||||
href="?inclbookmarked=0&incldead=1&spstate=0&page=561"><b>28051 - 28100</b></a> | <a
|
href="?inclbookmarked=0&incldead=1&spstate=0&page=561"><b>28051 - 28100</b></a> | <a
|
||||||
href="?inclbookmarked=0&incldead=1&spstate=0&page=562"><b>28101 - 28150</b></a> | <a
|
href="?inclbookmarked=0&incldead=1&spstate=0&page=562"><b>28101 - 28150</b></a> | <a
|
||||||
href="?inclbookmarked=0&incldead=1&spstate=0&page=563"><b>28151 - 28164</b></a></p>
|
href="?inclbookmarked=0&incldead=1&spstate=0&page=563"><b>28151 - 28164</b></a>
|
||||||
|
</p>
|
||||||
<table class="torrents" cellspacing="0" cellpadding="5" width="100%">
|
<table class="torrents" cellspacing="0" cellpadding="5" width="100%">
|
||||||
<tr>
|
<tr>
|
||||||
<td class="colhead" style="padding: 0px">类型</td>
|
<td class="colhead" style="padding: 0px">类型</td>
|
||||||
|
|
|
@ -17,13 +17,19 @@ import java.util.List;
|
||||||
public class HttpToolTest {
|
public class HttpToolTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetHtml() throws IOException {
|
public void testGetSeedList() throws IOException {
|
||||||
String htmlData = new String(this.getClass().getResourceAsStream("/test-seed-list-page.html").readAllBytes());
|
String htmlData = new String(this.getClass().getResourceAsStream("/test-seed-list-page.html").readAllBytes());
|
||||||
// log.info("htmlData: {}", htmlData);
|
|
||||||
Document parse = Jsoup.parse(htmlData);
|
Document parse = Jsoup.parse(htmlData);
|
||||||
List<SeedListItem> listItem = HtmlTool.getSeedListItem(parse);
|
List<SeedListItem> listItem = HtmlTool.getSeedListItem(parse);
|
||||||
for (SeedListItem seedListItem : listItem) {
|
for (SeedListItem seedListItem : listItem) {
|
||||||
log.info("item-->{}", seedListItem);
|
log.info("item-->{}", seedListItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetSeedTotal() throws IOException {
|
||||||
|
String htmlData = new String(this.getClass().getResourceAsStream("/test-seed-list-page.html").readAllBytes());
|
||||||
|
Document parse = Jsoup.parse(htmlData);
|
||||||
|
Integer pageTotal = HtmlTool.getPageTotal(parse);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue