mirror of
				https://github.com/LamGC/ContentGrabbingJi.git
				synced 2025-10-31 16:46:57 +00:00 
			
		
		
		
	[Delete] 删除不再使用的类和方法;
[Update] 优化Javadoc并设置编译注解, 优化代码; [Change] 调整部分日志的输出级别; [Change] RedisPoolCacheStore clear方法将根据返回信息确定是否清空成功; [Change] Dockerfile.sample 调整镜像构建步骤;
This commit is contained in:
		| @ -4,4 +4,5 @@ ENV jarFileName=ContentGrabbingJi-exec.jar | ||||
| COPY ${jarFileName} /program/CGJ.jar | ||||
| RUN mkdir /program/data | ||||
|  | ||||
| CMD cd /program/data && java -jar /program/CGJ.jar botMode | ||||
| WORKDIR /program/data | ||||
| CMD java -jar /program/CGJ.jar botMode | ||||
| @ -9,8 +9,9 @@ import com.google.gson.JsonElement; | ||||
| import com.google.gson.JsonObject; | ||||
| import net.lamgc.cgj.bot.framework.coolq.CQConfig; | ||||
| import net.lamgc.cgj.bot.framework.mirai.MiraiMain; | ||||
| import net.lamgc.cgj.pixiv.*; | ||||
| import net.lamgc.cgj.proxy.PixivAccessProxyServer; | ||||
| import net.lamgc.cgj.pixiv.PixivDownload; | ||||
| import net.lamgc.cgj.pixiv.PixivSearchBuilder; | ||||
| import net.lamgc.cgj.pixiv.PixivURL; | ||||
| import net.lamgc.plps.PixivLoginProxyServer; | ||||
| import net.lamgc.utils.base.ArgumentsProperties; | ||||
| import net.lamgc.utils.base.runner.Argument; | ||||
| @ -20,9 +21,7 @@ import org.apache.commons.io.IOUtils; | ||||
| import org.apache.http.HttpHost; | ||||
| import org.apache.http.HttpResponse; | ||||
| import org.apache.http.client.CookieStore; | ||||
| import org.apache.http.client.HttpClient; | ||||
| import org.apache.http.client.methods.HttpGet; | ||||
| import org.apache.http.message.BasicHeader; | ||||
| import org.apache.http.util.EntityUtils; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| @ -355,86 +354,16 @@ public class Main { | ||||
|                         builder, | ||||
|                         PixivURL.getPixivRefererLink(illustId) | ||||
|                 ); | ||||
|  | ||||
|                 /*log.info("正在下载..."); | ||||
|                 List<String> list = PixivDownload.getIllustAllPageDownload( | ||||
|                         HttpClientBuilder.create() | ||||
|                                 .setProxy(proxy) | ||||
|                                 .build(), | ||||
|                         illustId, PixivDownload.PageQuality.ORIGINAL);*/ | ||||
|             } | ||||
|         } | ||||
|         /* | ||||
|  | ||||
|         if(searchBuilder.getSearchArea().equals(PixivSearchBuilder.SearchArea.TOP)) { | ||||
|  | ||||
|         } else { | ||||
|             JsonArray illustsArray = resultBody | ||||
|                     .getAsJsonObject(searchBuilder.getSearchArea().jsonKey).getAsJsonArray("data"); | ||||
|             log.info("已找到与 {} 相关插图信息:", content); | ||||
|             int count = 1; | ||||
|             for (JsonElement jsonElement : illustsArray) { | ||||
|                 JsonObject illustObj = jsonElement.getAsJsonObject(); | ||||
|                 //TODO: 防止数据内混入无效内容, 需要检查对象是否有illustId | ||||
|                 if(!illustObj.has("illustId")) { | ||||
|                     continue; | ||||
|                 } | ||||
|                 int illustId = illustObj.get("illustId").getAsInt(); | ||||
|                 StringBuilder builder = new StringBuilder("["); | ||||
|                 illustObj.get("tags").getAsJsonArray().forEach(el -> builder.append(el.getAsString()).append(", ")); | ||||
|                 builder.replace(builder.length() - 2, builder.length(), "]"); | ||||
|                 log.info("({} / {})\n\t作品id: {}, \n\t作者名(作者id): {} ({}), \n\t作品标题: {}, \n\t作品Tags: {}, \n\t作品链接: {}", | ||||
|                         count++, | ||||
|                         illustsArray.size(), | ||||
|                         illustId, | ||||
|                         illustObj.get("userName").getAsString(), | ||||
|                         illustObj.get("userId").getAsInt(), | ||||
|                         illustObj.get("illustTitle").getAsString(), | ||||
|                         builder, | ||||
|                         PixivURL.getPixivRefererLink(illustId) | ||||
|                 ); | ||||
|             } | ||||
|         } | ||||
|         */ | ||||
|     } | ||||
|  | ||||
|  | ||||
|     @Command(defaultCommand = true) | ||||
|     public static void testRun() { | ||||
|         /*loadCookieStoreFromFile(); | ||||
|  | ||||
|         if(cookieStore == null){ | ||||
|             startPixivLoginProxyServer(); | ||||
|         }*/ | ||||
|  | ||||
|         //accessPixivToFile(); | ||||
|  | ||||
|         //startPixivAccessProxyServer(); | ||||
|  | ||||
|         //saveCookieStoreToFile(); | ||||
|         log.info("这里啥都没有哟w"); | ||||
|     } | ||||
|  | ||||
|     private static void loadCookieStoreFromFile() throws IOException { | ||||
|         log.info("正在加载CookieStore..."); | ||||
|         File storeFile = new File("./cookies.store"); | ||||
|         if(!storeFile.exists()){ | ||||
|             log.info("未找到CookieStore, 跳过加载."); | ||||
|             return; | ||||
|         } | ||||
|         ObjectInputStream stream = new ObjectInputStream(new FileInputStream(storeFile)); | ||||
|         Object result; | ||||
|         try { | ||||
|             result = stream.readObject(); | ||||
|         } catch (ClassNotFoundException e) { | ||||
|             log.error("加载出错", e); | ||||
|             return; | ||||
|         } | ||||
|         cookieStore = (CookieStore) result; | ||||
|         cookieStore.getCookies().forEach(cookie -> log.debug(cookie.getName() + ": " + cookie.getValue() + ", isExpired: " + cookie.isExpired(new Date()))); | ||||
|         log.info("CookieStore加载完成."); | ||||
|     } | ||||
|  | ||||
|     private static void saveCookieStoreToFile() throws IOException { | ||||
|         log.info("正在保存CookieStore..."); | ||||
|         File outputFile = new File("./cookies.store"); | ||||
| @ -484,75 +413,4 @@ public class Main { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private static void accessPixivToFile() throws IOException { | ||||
|         File cookieStoreFile = new File("./cookie.txt"); | ||||
|         if (!cookieStoreFile.exists() && !cookieStoreFile.createNewFile()) { | ||||
|             log.info("Cookie文件存储失败"); | ||||
|         } | ||||
|         /*log.info("正在写出Cookie, Cookie count: " + cookieStore.getCookies().size()); | ||||
|         FileWriter cookieWriter = new FileWriter(cookieStoreFile); | ||||
|         cookieStore.getCookies().forEach(cookie -> { | ||||
|             try { | ||||
|                 StringBuilder sb = new StringBuilder().append(cookie.getName()).append(" = ").append(cookie.getValue()); | ||||
|                 log.info("正在导出Cookie: " + sb.toString()); | ||||
|                 cookieWriter.append(sb.toString()).append("\n").flush(); | ||||
|             } catch (IOException e) { | ||||
|                 e.printStackTrace(); | ||||
|             } | ||||
|         }); | ||||
|         log.info("Cookie写出完成");*/ | ||||
|  | ||||
|         log.info("尝试通过捕获的Cookie访问Pixiv..."); | ||||
|         HttpClient httpClient = new PixivSession(new HttpHost("127.0.0.1", 1080), cookieStore).getHttpClient(); | ||||
|         HttpGet request = new HttpGet("https://www.pixiv.net"); | ||||
|         request.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:73.0) Gecko/20100101 Firefox/73.0"); | ||||
|         request.addHeader(new BasicHeader("accept-encoding", "gzip, deflate, br")); | ||||
|         request.addHeader(new BasicHeader("accept-language", "zh-CN,zh;q=0.9")); | ||||
|         StringBuilder cookieBuilder = new StringBuilder(); | ||||
|         cookieStore.getCookies().forEach(cookie -> { | ||||
|             if(cookie.isExpired(new Date())){ | ||||
|                 return; | ||||
|             } | ||||
|             cookieBuilder.append(cookie.getName()).append("=").append(cookie.getValue()).append("; "); | ||||
|         }); | ||||
|         request.addHeader("cookie", cookieBuilder.toString()); | ||||
|  | ||||
|         HttpResponse response = httpClient.execute(request); | ||||
|         log.info("正在写入文件..."); | ||||
|         File outFile = new File("./pixiv.html"); | ||||
|         if (outFile.createNewFile() && !outFile.exists()) { | ||||
|             log.info("文件创建失败!"); | ||||
|         }else { | ||||
|             new FileWriter(outFile).append(EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8)).flush(); | ||||
|         } | ||||
|  | ||||
|         Pixiv pixiv = new Pixiv(httpClient); | ||||
|         pixiv.getRecommend().forEach(illustMap -> { | ||||
|             StringBuilder builder = new StringBuilder(); | ||||
|             illustMap.forEach((key, value) -> builder.append(key).append(": ").append(value).append("\n")); | ||||
|             try { | ||||
|                 builder.append("download Link: ").append(Arrays.toString(pixiv.getAllDownloadLink(Integer.parseInt(illustMap.get(Pixiv.ATTR_ILLUST_ID))))); | ||||
|             } catch (IOException e) { | ||||
|                 log.error("获取下载链接时出错!", e); | ||||
|             } | ||||
|             log.info(builder.append("\n").toString()); | ||||
|         }); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     private static void startPixivAccessProxyServer(){ | ||||
|         log.info("正在启动访问代理服务器, 将浏览器相关缓存清空后, 使用浏览器进行访问以尝试Cookie正确性."); | ||||
|         final PixivAccessProxyServer accessProxyServer = new PixivAccessProxyServer(cookieStore, new ProxyConfig(ProxyType.SOCKS5, "127.0.0.1", 1080)); | ||||
|         Thread accessProxyServerThread = new Thread(() -> { | ||||
|             log.info("正在启动PAPS..."); | ||||
|             accessProxyServer.start(1007); | ||||
|             log.info("PAPS已关闭."); | ||||
|         }); | ||||
|         accessProxyServerThread.setName("AccessProxyServerThread"); | ||||
|         accessProxyServerThread.start(); | ||||
|         new Scanner(System.in).nextLine(); | ||||
|         log.info("关闭PAPS服务器..."); | ||||
|         accessProxyServer.close(); | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -684,7 +684,7 @@ public class BotCommandProcess { | ||||
|         if (!illustPreLoadDataCache.exists(illustIdStr) || flushCache) { | ||||
|             synchronized (illustIdStr) { | ||||
|                 if (!illustPreLoadDataCache.exists(illustIdStr) || flushCache) { | ||||
|                     log.info("IllustId {} 缓存失效, 正在更新...", illustId); | ||||
|                     log.debug("IllustId {} 缓存失效, 正在更新...", illustId); | ||||
|                     JsonObject preLoadDataObj = pixivDownload.getIllustPreLoadDataById(illustId) | ||||
|                             .getAsJsonObject("illust") | ||||
|                             .getAsJsonObject(Integer.toString(illustId)); | ||||
| @ -700,7 +700,7 @@ public class BotCommandProcess { | ||||
|  | ||||
|                     result = preLoadDataObj; | ||||
|                     illustPreLoadDataCache.update(illustIdStr, preLoadDataObj, expire); | ||||
|                     log.info("作品Id {} preLoadData缓存已更新(有效时间: {})", illustId, expire); | ||||
|                     log.debug("作品Id {} preLoadData缓存已更新(有效时间: {})", illustId, expire); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| @ -772,15 +772,16 @@ public class BotCommandProcess { | ||||
|         if(!rankingCache.exists(requestSign) || flushCache) { | ||||
|             synchronized(requestSign) { | ||||
|                 if(!rankingCache.exists(requestSign) || flushCache) { | ||||
|                     log.info("Ranking缓存失效, 正在更新...(RequestSign: {})", requestSign); | ||||
|                     log.debug("Ranking缓存失效, 正在更新...(RequestSign: {})", requestSign); | ||||
|                     List<JsonObject> rankingResult = pixivDownload.getRanking(contentType, mode, queryDate, 1, 500); | ||||
|                     long expireTime = 0; | ||||
|                     if(rankingResult.size() == 0) { | ||||
|                         log.info("数据获取失败, 将设置浮动有效时间以准备下次更新."); | ||||
|                         expireTime = 5400000 + expireTimeFloatRandom.nextInt(1800000); | ||||
|                         log.warn("数据获取失败, 将设置浮动有效时间以准备下次更新. (ExpireTime: {}ms)", expireTime); | ||||
|                     } | ||||
|                     result = new ArrayList<>(rankingResult).subList(start - 1, start + range - 1); | ||||
|                     rankingCache.update(requestSign, rankingResult, | ||||
|                             rankingResult.size() == 0 ? 5400000 + expireTimeFloatRandom.nextInt(1800000) : 0); | ||||
|                     log.info("Ranking缓存更新完成.(RequestSign: {})", requestSign); | ||||
|                     rankingCache.update(requestSign, rankingResult, expireTime); | ||||
|                     log.debug("Ranking缓存更新完成.(RequestSign: {})", requestSign); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @ -69,7 +69,7 @@ public class RandomRankingArtworksSender extends AutoSender { | ||||
|                     selectRanking, | ||||
|                     1, false); | ||||
|  | ||||
|             log.info("RankingResult.size: {}", rankingList.size()); | ||||
|             log.debug("RankingResult.size: {}", rankingList.size()); | ||||
|             if(rankingList.size() != 1) { | ||||
|                 log.error("排行榜选取失败!(获取到了多个结果)"); | ||||
|                 return; | ||||
|  | ||||
| @ -30,7 +30,7 @@ public class ImageCacheHandler implements EventHandler { | ||||
|     @SuppressWarnings("unused") | ||||
|     public void getImageToCache(ImageCacheObject event) { | ||||
|         if(cacheQueue.contains(event)) { | ||||
|             log.info("图片 {} 已存在相同缓存任务, 跳过.", event.getStoreFile().getName()); | ||||
|             log.debug("图片 {} 已存在相同缓存任务, 跳过.", event.getStoreFile().getName()); | ||||
|             return; | ||||
|         } else { | ||||
|             cacheQueue.add(event); | ||||
| @ -39,7 +39,7 @@ public class ImageCacheHandler implements EventHandler { | ||||
|         try { | ||||
|             log.info("图片 {} Event正在进行...({})", event.getStoreFile().getName(), Integer.toHexString(event.hashCode())); | ||||
|             File storeFile = event.getStoreFile(); | ||||
|             log.info("正在缓存图片 {} (Path: {})", storeFile.getName(), storeFile.getAbsolutePath()); | ||||
|             log.debug("正在缓存图片 {} (Path: {})", storeFile.getName(), storeFile.getAbsolutePath()); | ||||
|             try { | ||||
|                 if(!storeFile.exists() && !storeFile.createNewFile()) { | ||||
|                     log.error("无法创建文件(Path: {})", storeFile.getAbsolutePath()); | ||||
| @ -64,7 +64,7 @@ public class ImageCacheHandler implements EventHandler { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             log.info("正在下载...(Content-Length: {}KB)", response.getEntity().getContentLength() / 1024); | ||||
|             log.debug("正在下载...(Content-Length: {}KB)", response.getEntity().getContentLength() / 1024); | ||||
|             try(FileOutputStream fos = new FileOutputStream(storeFile)) { | ||||
|                 IOUtils.copy(response.getEntity().getContent(), fos); | ||||
|             } catch (IOException e) { | ||||
|  | ||||
| @ -82,9 +82,7 @@ public abstract class RedisPoolCacheStore<T> implements CacheStore<T> { | ||||
|     @Override | ||||
|     public boolean clear() { | ||||
|         try (Jedis jedis = jedisPool.getResource()) { | ||||
|             String result = jedis.flushDB(); | ||||
|             log.info("flushDB返回结果: {}", result); | ||||
|             return true; | ||||
|             return jedis.flushDB().equalsIgnoreCase("ok"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -158,13 +156,4 @@ public abstract class RedisPoolCacheStore<T> implements CacheStore<T> { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 替换原本的分隔符(.)为(:).<br/> | ||||
|      * 即将启用 | ||||
|      * @param key 要处理的键名 | ||||
|      * @return 处理后的键名 | ||||
|      */ | ||||
|     public static String replaceKey(String key) { | ||||
|         return key.replaceAll("\\.", ":"); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -24,19 +24,16 @@ public class CQPluginMain extends CQPlugin implements EventHandler { | ||||
|  | ||||
|     @Override | ||||
|     public int onPrivateMessage(CoolQ cq, CQPrivateMessageEvent event) { | ||||
|         //log.info("私聊消息到达: 发送者[{}], 消息内容: {}", event.getSender().getUserId(), event.getMessage()); | ||||
|         return processMessage(cq, event); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public int onGroupMessage(CoolQ cq, CQGroupMessageEvent event) { | ||||
|         //log.info("群消息到达: 群[{}], 发送者[{}], 消息内容: {}", event.getGroupId(), event.getSender().getUserId(), event.getMessage()); | ||||
|         return processMessage(cq, event); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public int onDiscussMessage(CoolQ cq, CQDiscussMessageEvent event) { | ||||
|         //log.info("讨论组消息到达: 群[{}], 发送者[{}], 消息内容: {}", event.getDiscussId(), event.getSender().getUserId(), event.getMessage()); | ||||
|         return processMessage(cq, event); | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -156,7 +156,7 @@ public class MiraiMessageSender implements MessageSender { | ||||
|                             } | ||||
|                         } | ||||
|                         imageIdCache.update(imageName, image.getImageId(), expireTime); | ||||
|                         log.info("imageName [{}] 缓存更新完成.(有效时间: {})", imageName, expireTime); | ||||
|                         log.debug("imageName [{}] 缓存更新完成.(有效时间: {})", imageName, expireTime); | ||||
|                     } else { | ||||
|                         log.debug("ImageName: [{}] 缓存命中.", imageName); | ||||
|                     } | ||||
|  | ||||
| @ -1,69 +0,0 @@ | ||||
| package net.lamgc.cgj.pixiv; | ||||
|  | ||||
| /** | ||||
|  * 插图(集)的信息 | ||||
|  */ | ||||
| public class IllustInfo{ | ||||
|  | ||||
|     /** | ||||
|      * 插图(集)ID | ||||
|      */ | ||||
|     public final int illustID; | ||||
|  | ||||
|     /** | ||||
|      * 第几页 | ||||
|      */ | ||||
|     public final int page; | ||||
|  | ||||
|     /** | ||||
|      * 插图标题 | ||||
|      */ | ||||
|     public final String title; | ||||
|  | ||||
|     /** | ||||
|      * 插图说明 | ||||
|      */ | ||||
|     public final String description; | ||||
|  | ||||
|     /** | ||||
|      * 插图标签 | ||||
|      */ | ||||
|     public final String[] tags; | ||||
|  | ||||
|     /** | ||||
|      * 插图图片长度 | ||||
|      */ | ||||
|     public final int width; | ||||
|  | ||||
|     /** | ||||
|      * 插图图片高度 | ||||
|      */ | ||||
|     public final int height; | ||||
|  | ||||
|     /** | ||||
|      * 作者名 | ||||
|      */ | ||||
|     public final String authorName; | ||||
|  | ||||
|     /** | ||||
|      * 作者用户ID | ||||
|      */ | ||||
|     public final int authorUserID; | ||||
|  | ||||
|     public IllustInfo(int illustID, String title, String description, String[] tags, int width, int height, String authorName, int authorUserID){ | ||||
|         this(illustID, 0, title, description, tags, width, height, authorName, authorUserID); | ||||
|     } | ||||
|  | ||||
|     public IllustInfo(int illustID, int p, String title, String description, String[] tags, int width, int height, String authorName, int authorUserID){ | ||||
|         this.illustID = illustID; | ||||
|         this.page = p; | ||||
|         this.title = title; | ||||
|         this.description = description; | ||||
|         this.tags = tags; | ||||
|         this.width = width; | ||||
|         this.height = height; | ||||
|         this.authorName = authorName; | ||||
|         this.authorUserID = authorUserID; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -1,267 +0,0 @@ | ||||
| package net.lamgc.cgj.pixiv; | ||||
|  | ||||
| import com.google.gson.JsonArray; | ||||
| import com.google.gson.JsonObject; | ||||
| import com.google.gson.JsonParser; | ||||
| import org.apache.http.HttpHost; | ||||
| import org.apache.http.HttpResponse; | ||||
| import org.apache.http.client.HttpClient; | ||||
| import org.apache.http.client.config.RequestConfig; | ||||
| import org.apache.http.client.methods.HttpGet; | ||||
| import org.apache.http.conn.ConnectionPoolTimeoutException; | ||||
| import org.apache.http.impl.client.HttpClientBuilder; | ||||
| import org.apache.http.util.EntityUtils; | ||||
| import org.jsoup.Jsoup; | ||||
| import org.jsoup.nodes.Document; | ||||
|  | ||||
| import java.io.ByteArrayInputStream; | ||||
| import java.io.ByteArrayOutputStream; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.nio.charset.StandardCharsets; | ||||
| import java.util.*; | ||||
|  | ||||
| public class Pixiv { | ||||
|  | ||||
|     /** | ||||
|      * illust Link | ||||
|      */ | ||||
|     public final static String ATTR_LINK = "link"; | ||||
|  | ||||
|     /** | ||||
|      * illust Id | ||||
|      */ | ||||
|     public final static String ATTR_ILLUST_ID = "illustId"; | ||||
|  | ||||
|     /** | ||||
|      * illust Title | ||||
|      */ | ||||
|     public final static String ATTR_TITLE = "title"; | ||||
|  | ||||
|     /** | ||||
|      * illust Author Name | ||||
|      */ | ||||
|     public final static String ATTR_AUTHOR_NAME = "authorName"; | ||||
|  | ||||
|     /** | ||||
|      * illust Author UserID | ||||
|      */ | ||||
|     public final static String ATTR_AUTHOR_ID = "authorId"; | ||||
|  | ||||
|     private final HttpClient httpClient; | ||||
|  | ||||
|     public Pixiv(HttpClient client){ | ||||
|         this.httpClient = client; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 使用帐号密码登录Pixiv | ||||
|      * @param PixivID Pixiv账户登录名 | ||||
|      * @param Password Pixiv帐号密码 | ||||
|      * @throws IOException 当登录连接出现异常时抛出 | ||||
|      * @deprecated {@link PixivSession#Login(String, String)} 已经废除, 故本方法不可用 | ||||
|      */ | ||||
|     public Pixiv(String PixivID, String Password) throws IOException { | ||||
|         this(PixivID, Password, null); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 使用帐号密码登录Pixiv | ||||
|      * @param PixivID Pixiv账户登录名 | ||||
|      * @param Password Pixiv帐号密码 | ||||
|      * @param proxy 代理设置 | ||||
|      * @throws IOException 当登录连接出现异常时抛出 | ||||
|      * @deprecated {@link PixivSession#Login(String, String)} 已经废除, 故本方法不可用 | ||||
|      */ | ||||
|     public Pixiv(String PixivID, String Password, HttpHost proxy) throws IOException { | ||||
|         PixivSession pixivSession = new PixivSession(proxy, null); | ||||
|         if(pixivSession.Login(PixivID, Password)){ | ||||
|             System.out.println("P站登录成功!"); | ||||
|         }else{ | ||||
|             System.out.println("P站登录失败!错误信息: " + pixivSession.getErrMsg()); | ||||
|             throw new RuntimeException(pixivSession.getErrMsg()); | ||||
|         } | ||||
|         //httpClient = pixivSession.getHttpClient(); | ||||
|         httpClient = HttpClientBuilder.create() | ||||
|                 .setDefaultCookieStore(pixivSession.getCookieStore()) | ||||
|                 .build(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取首页推荐列表 | ||||
|      * @return 首页推荐列表, 一个Map对应一个推荐项, 使用<code>ATTR_</code>开头常量访问即可 | ||||
|      * @throws IOException | ||||
|      */ | ||||
|     public List<Map<String, String>> getRecommend() throws IOException { | ||||
|         HttpGet getRequest = new HttpGet(PixivURL.PIXIV_INDEX_URL); | ||||
|         HttpResponse response = httpClient.execute(getRequest); | ||||
|         String pageAsXML = EntityUtils.toString(response.getEntity(),"utf-8"); | ||||
|  | ||||
|         //获取推荐图列表(li) | ||||
|         //System.out.println(pageAsXML); | ||||
|  | ||||
|         Document document = Jsoup.parse(pageAsXML); | ||||
|  | ||||
|         List<String> links  = document.select("._image-items.gtm-illust-recommend-zone>li>.gtm-illust-recommend-thumbnail-link").eachAttr("href"); | ||||
|         List<String> illustId  = document.select("._image-items.gtm-illust-recommend-zone>li>.gtm-illust-recommend-thumbnail-link").eachAttr("data-gtm-recommend-illust-id"); | ||||
|         List<String> title = document.select("._image-items.gtm-illust-recommend-zone>li>.gtm-illust-recommend-title>h1").eachAttr("title"); | ||||
|         List<String> authorName = document.select("._image-items.gtm-illust-recommend-zone>li>.gtm-illust-recommend-user-name").eachText(); | ||||
|         List<String> authorId = document.select("._image-items.gtm-illust-recommend-zone>li>.gtm-illust-recommend-user-name").eachAttr("data-user_id"); | ||||
|  | ||||
|         List<Map<String, String>> recommendList = new ArrayList<>(); | ||||
|         for(int i = 0; i < links.size(); i++){ | ||||
|             //System.out.println(links.get(i)); | ||||
|             Map<String, String> info = new HashMap<>(); | ||||
|             info.put(ATTR_LINK, PixivURL.PIXIV_INDEX_URL + links.get(i)); | ||||
|             info.put(ATTR_ILLUST_ID, illustId.get(i)); | ||||
|             info.put(ATTR_TITLE, title.get(i)); | ||||
|             info.put(ATTR_AUTHOR_NAME, authorName.get(i)); | ||||
|             info.put(ATTR_AUTHOR_ID, authorId.get(i)); | ||||
|             recommendList.add(info); | ||||
|         } | ||||
|         return recommendList; | ||||
|     } | ||||
|  | ||||
|     public String[] getAllDownloadLink(int illustID) throws IOException { | ||||
|         HttpGet illustPage = new HttpGet(PixivURL.PIXIV_ILLUST_API_URL.replaceAll("\\{illustId}", String.valueOf(illustID))); | ||||
|         HttpResponse response = httpClient.execute(illustPage); | ||||
|         String pageAsXML = EntityUtils.toString(response.getEntity(),"utf-8"); | ||||
|         //System.out.println(pageAsXML); | ||||
|         JsonObject resultObj = (JsonObject) new JsonParser().parse(pageAsXML); | ||||
|         if(!resultObj.get("error").getAsBoolean()){ | ||||
|             JsonArray bodyArray = resultObj.get("body").getAsJsonArray(); | ||||
|             int length = bodyArray.size(); | ||||
|             String[] result = new String[length]; | ||||
|             for(int i = 0; i < length; i++){ | ||||
|                 JsonObject childObj = bodyArray.get(i).getAsJsonObject(); | ||||
|                 result[i] = childObj.get("urls").getAsJsonObject().get("original").getAsString(); | ||||
|             } | ||||
|             return result; | ||||
|         }else{ | ||||
|             return null; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * 下载P站图片 | ||||
|      * @param illustID 插图ID | ||||
|      * @return 成功返回图片输入流,失败或为多图则返回null | ||||
|      */ | ||||
|     public InputStream[] downloadIllustImage(int illustID) throws IOException { | ||||
|         String[] links = getAllDownloadLink(illustID); | ||||
|         List<InputStream> inputStreamList = new ArrayList<>(); | ||||
|         int count = 1; | ||||
|         boolean retry = false; | ||||
|         for(int i = 0; i < links.length; i++){ | ||||
|             try { | ||||
|                 long sleepTime = (new Random().nextInt(4) + 2) * 1000; | ||||
|                 System.out.println("nextTime: " + (float)(sleepTime / 1000)); | ||||
|                 Thread.sleep(sleepTime); | ||||
|             } catch (InterruptedException ignored) {} | ||||
|             String link = links[i]; | ||||
|             System.out.print("page:" + count++ + "/" + links.length + " ..."); | ||||
|             HttpGet imgGet = new HttpGet(link); | ||||
|             //关键!如果不加上Referer的话,会返回403 | ||||
|             imgGet.setHeader("Referer", PixivURL.PIXIV_ILLUST_MEDIUM_URL.replaceAll("\\{illustId}", String.valueOf(illustID))); | ||||
|             RequestConfig config = RequestConfig.custom() | ||||
|                     .setConnectTimeout(20 * 1000) | ||||
|                     .setConnectionRequestTimeout(20 * 1000) | ||||
|                     .setSocketTimeout(30 * 1000) | ||||
|                     .build(); | ||||
|             imgGet.setConfig(config); | ||||
|             HttpResponse response; | ||||
|             try { | ||||
|                 response = httpClient.execute(imgGet); | ||||
|             }catch(ConnectionPoolTimeoutException e){ | ||||
|                 if(retry){ | ||||
|                     retry = false; | ||||
|                     System.out.println("获取失败,跳过..."); | ||||
|                     continue; | ||||
|                 } | ||||
|                 System.out.println("连接超时,重新获取..."); | ||||
|                 retry = true; | ||||
|                 i--; | ||||
|                 continue; | ||||
|             } | ||||
|             retry = false; | ||||
|  | ||||
|             ByteArrayOutputStream cacheOutputStream = new ByteArrayOutputStream((int)response.getEntity().getContentLength()); | ||||
|             InputStream content = response.getEntity().getContent(); | ||||
|             int readLength; | ||||
|             byte[] cache = new byte[4096]; | ||||
|             while((readLength = content.read(cache)) != -1){ | ||||
|                 cacheOutputStream.write(cache, 0, readLength); | ||||
|             } | ||||
|             byte[] data = cacheOutputStream.toByteArray(); | ||||
|             //System.out.println("读到数据: " + data.length); | ||||
|             inputStreamList.add(new ByteArrayInputStream(data)); | ||||
|             System.out.println("done!(length: " + response.getEntity().getContentLength() + ")"); | ||||
|  | ||||
|         } | ||||
|         return inputStreamList.toArray(new InputStream[0]); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 下载P站图片 | ||||
|      * @param illustID 插图ID | ||||
|      * @return 成功返回图片输入流,失败或为多图则返回null | ||||
|      */ | ||||
|     public InputStream downloadIllustImages(int illustID){ | ||||
|         throw new UnsupportedOperationException(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 通过解析插图详情页获取 | ||||
|      * - 插图标题 | ||||
|      * - 插图作者(及其UserId) | ||||
|      * - 插图上传时间 | ||||
|      * - 插图标签(原始标签) | ||||
|      * ... | ||||
|      * @return 成功返回IllustInfo对象,失败返回null | ||||
|      */ | ||||
|     public IllustInfo[] getIllustInfo(int[] illustIDs) throws IOException { | ||||
|         //获取Api | ||||
|         HttpGet apiRequest = new HttpGet(PixivURL.getPixivIllustInfoAPI(illustIDs)); | ||||
|         HttpResponse response = httpClient.execute(apiRequest); | ||||
|         String resultText = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8); | ||||
|         System.out.println(resultText); | ||||
|         JsonObject resultObj = ((JsonObject) new JsonParser().parse(resultText)); | ||||
|         if(resultObj.get("error").getAsBoolean()){ | ||||
|             System.err.println("获取失败!"); | ||||
|             return null; | ||||
|         } | ||||
|         List<IllustInfo> illustInfoList = new ArrayList<>(); | ||||
|         JsonArray illustArray = resultObj.get("body").getAsJsonObject().get("illusts").getAsJsonArray(); | ||||
|         illustArray.forEach(jsonElement -> { | ||||
|             JsonObject illustInfoObj = jsonElement.getAsJsonObject(); | ||||
|             JsonArray tagsArray = illustInfoObj.get("tags").getAsJsonArray(); | ||||
|             String[] tags = new String[tagsArray.size()]; | ||||
|             for(int i = 0; i < tags.length; i++){ | ||||
|                 tags[i] = tagsArray.get(i).getAsString(); | ||||
|             } | ||||
|             //TODO: 通过不需要作者id就能获取图片信息的api无法获取图片尺寸 | ||||
|             IllustInfo illustInfo = new IllustInfo( | ||||
|                     illustInfoObj.get("workId").getAsInt(), | ||||
|                     illustInfoObj.get("title").getAsString(), | ||||
|                     null, | ||||
|                     tags, | ||||
|                     -1, | ||||
|                     -1, | ||||
|                     illustInfoObj.get("userName").getAsString(), | ||||
|                     illustInfoObj.get("userId").getAsInt() | ||||
|             ); | ||||
|         }); | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取指定用户的所有插画 | ||||
|      */ | ||||
|     public void getUserAllIllustTest() { | ||||
|  | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
| @ -9,6 +9,13 @@ import java.util.Date; | ||||
| import java.util.HashSet; | ||||
| import java.util.Objects; | ||||
|  | ||||
| /** | ||||
|  * Pixiv搜索URL构造器 | ||||
|  * <p>该构造器通过分析Pixiv搜索链接可用的参数而开发, 对搜索链接的构造有高度自定义能力.</p> | ||||
|  * @author LamGC | ||||
|  * @see PixivURL#PIXIV_SEARCH_CONTENT_URL | ||||
|  */ | ||||
| @SuppressWarnings("ALL") | ||||
| public class PixivSearchBuilder { | ||||
|  | ||||
|     private final String content; | ||||
|  | ||||
| @ -1,171 +0,0 @@ | ||||
| package net.lamgc.cgj.pixiv; | ||||
|  | ||||
| import com.google.gson.JsonObject; | ||||
| import com.google.gson.JsonParser; | ||||
| import org.apache.http.Header; | ||||
| import org.apache.http.HttpHost; | ||||
| import org.apache.http.HttpResponse; | ||||
| import org.apache.http.NameValuePair; | ||||
| import org.apache.http.client.CookieStore; | ||||
| import org.apache.http.client.HttpClient; | ||||
| import org.apache.http.client.entity.UrlEncodedFormEntity; | ||||
| import org.apache.http.client.methods.HttpGet; | ||||
| import org.apache.http.client.methods.HttpPost; | ||||
| import org.apache.http.impl.client.BasicCookieStore; | ||||
| import org.apache.http.impl.client.HttpClients; | ||||
| import org.apache.http.message.BasicHeader; | ||||
| import org.apache.http.message.BasicNameValuePair; | ||||
| import org.apache.http.util.EntityUtils; | ||||
| import org.jsoup.Jsoup; | ||||
| import org.jsoup.nodes.Document; | ||||
|  | ||||
| import java.io.IOException; | ||||
| import java.nio.charset.StandardCharsets; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
|  | ||||
| public class PixivSession { | ||||
|  | ||||
|     public static final String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36"; | ||||
|  | ||||
|     /** | ||||
|      * 全登陆过程的关键, | ||||
|      * 保存会话用的cookieStore! | ||||
|      */ | ||||
|     private CookieStore cookieStore = new BasicCookieStore(); | ||||
|  | ||||
|     /** | ||||
|      * 可以直接使用的HttpClient对象 | ||||
|      */ | ||||
|     private HttpClient httpClient; | ||||
|  | ||||
|     /** | ||||
|      * 最后一次登录的错误信息 | ||||
|      */ | ||||
|     private String errMsg; | ||||
|  | ||||
|     public PixivSession(){ | ||||
|         this(null); | ||||
|     } | ||||
|  | ||||
|     public PixivSession(CookieStore cookieStore){ | ||||
|         this(null, cookieStore); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 创建一个Pixiv登录会话 | ||||
|      */ | ||||
|     public PixivSession(HttpHost proxy, CookieStore cookieStore) { | ||||
|         if(cookieStore != null){ | ||||
|             this.cookieStore = cookieStore; | ||||
|         } | ||||
|         List<Header> defaultHeader = new ArrayList<>(); | ||||
|         defaultHeader.add(new BasicHeader("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9")); | ||||
|         defaultHeader.add(new BasicHeader("user-agent", PixivSession.USER_AGENT)); | ||||
|         defaultHeader.add(new BasicHeader("accept-encoding", "gzip, deflate, br")); | ||||
|         defaultHeader.add(new BasicHeader("accept-language", "zh-CN,zh;q=0.9")); | ||||
|  | ||||
|         /*defaultHeader.add(new BasicHeader("sec-fetch-mode", "navigate")); | ||||
|         defaultHeader.add(new BasicHeader("sec-fetch-site", "same-origin")); | ||||
|         defaultHeader.add(new BasicHeader("upgrade-insecure-requests", "1"));*/ | ||||
|         //创建一个Http访问器 | ||||
|         httpClient = HttpClients.custom() | ||||
|                 .setDefaultCookieStore(cookieStore) | ||||
|                 .setDefaultHeaders(defaultHeader) | ||||
|                 .setProxy(proxy) | ||||
|                 .build(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 程序自行通过帐号密码登录Pixiv. | ||||
|      * @param PixivID Pixiv帐号 | ||||
|      * @param Password Pixiv密码 | ||||
|      * @return 登录成功返回true | ||||
|      * @throws IOException 当登录抛出异常时返回 | ||||
|      * @deprecated Pixiv已经新增Google人机验证, 程序已无法自行登录Pixiv | ||||
|      */ | ||||
|     public boolean Login(String PixivID, String Password) throws IOException { | ||||
|         // 获取登录接口所需的PostKey | ||||
|         String post_key = getPostKey(); | ||||
|         HttpPost postRequest = new HttpPost(PixivURL.PIXIV_LOGIN_URL); //https://accounts.pixiv.net/api/login?lang=zh | ||||
|         List<NameValuePair> params = new ArrayList<>(); | ||||
|         params.add(new BasicNameValuePair("pixiv_id", PixivID)); | ||||
|         params.add(new BasicNameValuePair("password", Password)); | ||||
|         params.add(new BasicNameValuePair("post_key", post_key)); | ||||
|         //Form编码表单,作为Post的数据 | ||||
|         postRequest.setEntity(new UrlEncodedFormEntity(params, StandardCharsets.UTF_8)); | ||||
|         //启动访问 | ||||
|         HttpResponse response = httpClient.execute(postRequest); | ||||
|         //获取接口返回数据 | ||||
|         String httpXML = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8); | ||||
|         System.out.println(httpXML); | ||||
|         JsonObject responseJson = (JsonObject) new JsonParser().parse(httpXML); | ||||
|         if(!responseJson.get("error").getAsBoolean() && !responseJson.get("body").getAsJsonObject().has("validation_errors")){ | ||||
|             errMsg = null; | ||||
|             return true; | ||||
|         }else{ | ||||
|             errMsg = responseJson.get("body").getAsJsonObject().get("validation_errors").toString(); | ||||
|             //System.err.println("登录失败!MSG: " + errMsg); | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 登录前准备, 获取PostKey | ||||
|      * @return Post_Key | ||||
|      */ | ||||
|     private String getPostKey() throws IOException { | ||||
|         //创建请求,获取PostKey | ||||
|         HttpGet getRequest = new HttpGet(PixivURL.PIXIV_LOGIN_PAGE_URL); | ||||
|         //设置请求 | ||||
|         //getRequest.setConfig(config); | ||||
|         getRequest.setHeader("User-Agent", USER_AGENT); | ||||
|         //启动访问 | ||||
|         HttpResponse response = httpClient.execute(getRequest); | ||||
|         //获取网页内容 | ||||
|         String pageAsXML = EntityUtils.toString(response.getEntity(),"utf-8"); | ||||
|         //创建Http解析器 | ||||
|         Document document = Jsoup.parse(pageAsXML); | ||||
|         //获取init-config内容 | ||||
|         String init_config = document.getElementById("init-config").val(); | ||||
|         //System.out.println(init_config); | ||||
|         //创建Json解析器解析init-config | ||||
|         JsonObject initConfigObj = (JsonObject) new JsonParser().parse(init_config); | ||||
|         //检查是否有postKey | ||||
|         if(!initConfigObj.has("pixivAccount.postKey")){ | ||||
|             throw new RuntimeException("postKey获取失败!可能是Pixiv修改了登录过程!"); | ||||
|         } | ||||
|         //获取postKey | ||||
|         return initConfigObj.get("pixivAccount.postKey").getAsString(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取CookieStore | ||||
|      * @return CookieStore | ||||
|      */ | ||||
|     public CookieStore getCookieStore(){ | ||||
|         return cookieStore; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取可直接使用的HttpClient对象 | ||||
|      * @return 已配置好的HttpClient对象 | ||||
|      */ | ||||
|     public HttpClient getHttpClient(){ | ||||
|         return this.httpClient; | ||||
|     } | ||||
|  | ||||
|     public boolean hasError(){ | ||||
|         return errMsg == null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取错误信息 | ||||
|      * @return 返回登录错误信息 | ||||
|      * @deprecated {@link #Login(String, String)}已经废除, 故本接口废除 | ||||
|      */ | ||||
|     public String getErrMsg(){ | ||||
|         return errMsg; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -1,16 +0,0 @@ | ||||
| package net.lamgc.cgj.pixiv; | ||||
|  | ||||
| public class PixivTag { | ||||
|  | ||||
|     public static PixivTag create(String tagName) { | ||||
|  | ||||
|  | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     private PixivTag() { | ||||
|  | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
| @ -9,6 +9,7 @@ import java.util.GregorianCalendar; | ||||
| /** | ||||
|  * 目前已整理的一些Pixiv接口列表 | ||||
|  */ | ||||
| @SuppressWarnings("unused") | ||||
| public class PixivURL { | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -26,8 +26,7 @@ import java.util.zip.ZipEntry; | ||||
| import java.util.zip.ZipInputStream; | ||||
|  | ||||
| /** | ||||
|  * Pixiv动图构建器. | ||||
|  * 可便捷的接收并处理动图. | ||||
|  * Pixiv动图构建器 | ||||
|  */ | ||||
| public final class PixivUgoiraBuilder { | ||||
|  | ||||
|  | ||||
| @ -1,31 +0,0 @@ | ||||
| package net.lamgc.cgj.util; | ||||
|  | ||||
| import org.apache.http.client.CookieStore; | ||||
| import org.apache.http.impl.client.BasicCookieStore; | ||||
| import org.apache.http.impl.cookie.BasicClientCookie; | ||||
|  | ||||
| import java.util.Date; | ||||
|  | ||||
| public class CookieUtil { | ||||
|  | ||||
|     /** | ||||
|      * 将{@link java.net.CookieStore}转换到{@link CookieStore} | ||||
|      * @param netCookieStore java.net.CookieStore | ||||
|      * @return org.apache.http.client.CookieStore | ||||
|      */ | ||||
|     public static CookieStore NAParse(java.net.CookieStore netCookieStore){ | ||||
|         CookieStore apacheCookieStore = new BasicCookieStore(); | ||||
|         netCookieStore.getCookies().forEach(netCookie -> { | ||||
|             BasicClientCookie aCookie = new BasicClientCookie(netCookie.getName(), netCookie.getValue()); | ||||
|             aCookie.setComment(netCookie.getComment()); | ||||
|             aCookie.setDomain(netCookie.getDomain()); | ||||
|             aCookie.setExpiryDate(new Date(netCookie.getMaxAge())); | ||||
|             aCookie.setPath(netCookie.getPath()); | ||||
|             aCookie.setSecure(netCookie.getSecure()); | ||||
|             aCookie.setVersion(netCookie.getVersion()); | ||||
|             apacheCookieStore.addCookie(aCookie); | ||||
|         }); | ||||
|         return apacheCookieStore; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -7,7 +7,7 @@ import net.lamgc.utils.base.runner.StringParameterParser; | ||||
| public class PagesQualityParser implements StringParameterParser<PixivDownload.PageQuality> { | ||||
|  | ||||
|     @Override | ||||
|     public PixivDownload.PageQuality parse(String strValue) throws Exception { | ||||
|     public PixivDownload.PageQuality parse(String strValue) { | ||||
|         return PixivDownload.PageQuality.valueOf(strValue.toUpperCase()); | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -181,19 +181,6 @@ public class PixivDownloadTest { | ||||
|         log.info("正在调用方法..."); | ||||
|         try { | ||||
|             pixivDownload.getRankingAsInputStream(null, null, queryDate, 5, 50, PixivDownload.PageQuality.ORIGINAL, (rank, link, rankInfo, inputStream) -> { | ||||
|                 /*try { | ||||
|  | ||||
|                     ZipEntry entry = new ZipEntry("Rank" + rank + "-" + link.substring(link.lastIndexOf("/") + 1)); | ||||
|                     entry.setComment(rankInfo.toString()); | ||||
|                     log.info("正在写入: " + entry.getName()); | ||||
|                     zos.putNextEntry(entry); | ||||
|                     IOUtils.copy(inputStream, zos); | ||||
|                     zos.flush(); | ||||
|                     log.info("已成功写入 {}", entry.getName()); | ||||
|                     inputStream.close(); | ||||
|                 } catch (IOException e) { | ||||
|                     log.error("写入文件项时发生异常", e); | ||||
|                 }*/ | ||||
|                 log.info("空操作"); | ||||
|             }); | ||||
|         } finally { | ||||
|  | ||||
		Reference in New Issue
	
	Block a user