From 6ac3e091f17debe15c5df23f64cf329af9a9a940 Mon Sep 17 00:00:00 2001 From: GaoGeng <3123557312@qq.com> Date: Mon, 1 Jun 2026 09:03:38 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E6=96=87=E4=BB=B6=E8=87=B3?= =?UTF-8?q?=20'project'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...02402050211-高耿-期末实验报告.docx | Bin 0 -> 32877 bytes project/App.java | 41 ++++ project/Command.java | 6 + project/TestC.java | 19 ++ project/TestCrawler.java | 210 ++++++++++++++++++ 5 files changed, 276 insertions(+) create mode 100644 project/202402050211-高耿-期末实验报告.docx create mode 100644 project/App.java create mode 100644 project/Command.java create mode 100644 project/TestC.java create mode 100644 project/TestCrawler.java diff --git a/project/202402050211-高耿-期末实验报告.docx b/project/202402050211-高耿-期末实验报告.docx new file mode 100644 index 0000000000000000000000000000000000000000..6becbb410bfebefe613fc17fd78c87b7bab0c33f GIT binary patch literal 32877 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 allMovies = new ArrayList<>(); + List doubanMovies = new ArrayList<>(); + List quotesMovies = new ArrayList<>(); + List tencentMovies = new ArrayList<>(); + + // Crawl Douban + System.out.println("\n" + "-".repeat(80)); + System.out.println("Crawling Douban Movies..."); + System.out.println("-".repeat(80)); + try { + DoubanCrawler doubanCrawler = new DoubanCrawler(); + doubanMovies = doubanCrawler.crawl(); + allMovies.addAll(doubanMovies); + System.out.println("\nDouban crawling completed! Got " + doubanMovies.size() + " movies"); + printMovieList("Douban", doubanMovies); + } catch (Exception e) { + System.err.println("Douban crawling error: " + e.getMessage()); + } + + // Crawl Quotes + System.out.println("\n" + "-".repeat(80)); + System.out.println("Crawling Quotes to Movies..."); + System.out.println("-".repeat(80)); + try { + QuotesCrawler quotesCrawler = new QuotesCrawler(); + quotesMovies = quotesCrawler.crawl(); + allMovies.addAll(quotesMovies); + System.out.println("\nQuotes crawling completed! Got " + quotesMovies.size() + " movies"); + printMovieList("Quotes", quotesMovies); + } catch (Exception e) { + System.err.println("Quotes crawling error: " + e.getMessage()); + } + + // Crawl Tencent + System.out.println("\n" + "-".repeat(80)); + System.out.println("Crawling Tencent Movies..."); + System.out.println("-".repeat(80)); + try { + TencentCrawler tencentCrawler = new TencentCrawler(); + tencentMovies = tencentCrawler.crawl(); + allMovies.addAll(tencentMovies); + System.out.println("\nTencent crawling completed! Got " + tencentMovies.size() + " movies"); + printMovieList("Tencent", tencentMovies); + } catch (Exception e) { + System.err.println("Tencent crawling error: " + e.getMessage()); + } + + // Sort by rating descending + allMovies.sort(Comparator.comparing(Movie::getRating).reversed()); + + // Show summary + System.out.println("\n\n" + "=".repeat(80)); + System.out.println(" Crawling Summary"); + System.out.println("=".repeat(80)); + System.out.println("\nData statistics:"); + System.out.println(" - Douban: " + doubanMovies.size() + " movies"); + System.out.println(" - Quotes: " + quotesMovies.size() + " movies"); + System.out.println(" - Tencent: " + tencentMovies.size() + " movies"); + System.out.println(" - Total: " + allMovies.size() + " movies"); + + System.out.println("\nTop 50 Movies:"); + System.out.println("-".repeat(80)); + System.out.printf("%-6s %-35s %-10s %-15s %-12s %-15s %-10s\n", + "Rank", "Title", "Rating", "Source", "Year", "Director", "Actors"); + System.out.println("-".repeat(80)); + + int count = 0; + for (Movie movie : allMovies) { + if (count >= 50) break; + System.out.printf("%-6d %-35s %-10.1f %-15s %-12s %-15s %-10s\n", + count + 1, + truncate(movie.getTitle(), 35), + movie.getRating() != null ? movie.getRating() : 0.0, + movie.getSource(), + movie.getReleaseDate() != null && !movie.getReleaseDate().isEmpty() ? movie.getReleaseDate() : "Unknown", + truncate(movie.getDirector(), 15), + truncate(movie.getActors(), 10)); + count++; + } + + System.out.println("-".repeat(80) + "\n"); + + // Save to CSV file + String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss")); + String csvFilename = "movies_" + timestamp + ".csv"; + try { + saveToCSV(allMovies, doubanMovies, quotesMovies, tencentMovies, csvFilename); + System.out.println("Data saved to file: " + csvFilename); + System.out.println(" - Contains complete data, can be opened directly in Excel"); + } catch (IOException e) { + System.err.println("Save CSV error: " + e.getMessage()); + } + + System.out.println("\n" + "=".repeat(80)); + System.out.println(" Program completed!"); + System.out.println("=".repeat(80) + "\n"); + } + + private static void printMovieList(String source, List movies) { + System.out.println("\n" + source + " Movie List (First 30):"); + System.out.println("-".repeat(80)); + System.out.printf("%-6s %-35s %-10s %-12s %-15s %-10s\n", + "No.", "Title", "Rating", "Year", "Director", "Source"); + System.out.println("-".repeat(80)); + + int index = 0; + for (Movie movie : movies) { + if (index >= 30) break; + System.out.printf("%-6d %-35s %-10.1f %-12s %-15s %-10s\n", + index + 1, + truncate(movie.getTitle(), 35), + movie.getRating() != null ? movie.getRating() : 0.0, + movie.getReleaseDate() != null && !movie.getReleaseDate().isEmpty() ? movie.getReleaseDate() : "Unknown", + truncate(movie.getDirector(), 15), + movie.getSource()); + index++; + } + System.out.println("-".repeat(80)); + } + + private static void saveToCSV(List allMovies, List doubanMovies, + List quotesMovies, List tencentMovies, + String filename) throws IOException { + try (BufferedWriter writer = new BufferedWriter(new FileWriter(filename))) { + // Write header + writer.write("No.,Title,Rating,Director,Actors,Year,Source"); + writer.newLine(); + + // Write all movies + writer.newLine(); + writer.write("All Movies (Sorted by Rating)"); + writer.newLine(); + writeMoviesToCSV(writer, allMovies); + + // Write Douban movies + writer.newLine(); + writer.write("Douban Movies"); + writer.newLine(); + writeMoviesToCSV(writer, doubanMovies); + + // Write Quotes movies + writer.newLine(); + writer.write("Quotes Movies"); + writer.newLine(); + writeMoviesToCSV(writer, quotesMovies); + + // Write Tencent movies + writer.newLine(); + writer.write("Tencent Movies"); + writer.newLine(); + writeMoviesToCSV(writer, tencentMovies); + } + } + + private static void writeMoviesToCSV(BufferedWriter writer, List movies) throws IOException { + int index = 0; + for (Movie movie : movies) { + String line = String.format("%d,\"%s\",%.1f,\"%s\",\"%s\",\"%s\",\"%s\"", + index + 1, + escapeCSV(movie.getTitle()), + movie.getRating() != null ? movie.getRating() : 0.0, + escapeCSV(movie.getDirector()), + escapeCSV(movie.getActors()), + escapeCSV(movie.getReleaseDate()), + escapeCSV(movie.getSource())); + writer.write(line); + writer.newLine(); + index++; + } + } + + private static String escapeCSV(String str) { + if (str == null || str.isEmpty()) { + return ""; + } + if (str.contains(",") || str.contains("\"") || str.contains("\n")) { + return "\"" + str.replace("\"", "\"\"") + "\""; + } + return str; + } + + private static String truncate(String str, int maxLength) { + if (str == null || str.isEmpty()) { + return ""; + } + return str.length() > maxLength ? str.substring(0, maxLength - 3) + "..." : str; + } +}