diff --git a/实验四/AnimatedMovie.java b/实验四/AnimatedMovie.java new file mode 100644 index 0000000..d5680d7 --- /dev/null +++ b/实验四/AnimatedMovie.java @@ -0,0 +1,13 @@ +public class AnimatedMovie extends Movie { + private String studio; + + public AnimatedMovie(String title, int year, double rating, String genre, String studio) { + super(title, year, rating, genre); + this.studio = studio; + } + + @Override + public void play() { + System.out.println("动画电影播放:" + getTitle() + ",制作公司:" + studio); + } +} diff --git a/实验四/BaseMovieCrawler.java b/实验四/BaseMovieCrawler.java new file mode 100644 index 0000000..ff85d09 --- /dev/null +++ b/实验四/BaseMovieCrawler.java @@ -0,0 +1,9 @@ +import org.jsoup.nodes.Element; +import java.util.List; + +public abstract class BaseMovieCrawler implements MovieCrawlerInterface { + public abstract List crawl(int limit); + + // 只保留带两个参数的抽象方法 + protected abstract Movie parseMovie(Element element, String type); +} \ No newline at end of file diff --git a/实验四/DouyinMovie.java b/实验四/DouyinMovie.java new file mode 100644 index 0000000..3f7c5ed --- /dev/null +++ b/实验四/DouyinMovie.java @@ -0,0 +1,13 @@ +public class DouyinMovie extends Movie { + private String hotValue; + + public DouyinMovie(String title, int year, double rating, String genre, String hotValue) { + super(title, year, rating, genre); + this.hotValue = hotValue; + } + + @Override + public void play() { + System.out.println("抖音视频:" + getTitle() + ",热度:" + hotValue); + } +} \ No newline at end of file diff --git a/实验四/Main.java b/实验四/Main.java new file mode 100644 index 0000000..df17e68 --- /dev/null +++ b/实验四/Main.java @@ -0,0 +1,12 @@ +import java.util.List; + +public class Main { + public static void main(String[] args) { + MovieCrawler crawler = new MovieCrawler(); + List list = crawler.crawl(2); // 每个网站爬2条 + + for (Movie m : list) { + m.play(); + } + } +} \ No newline at end of file diff --git a/实验四/Movie.java b/实验四/Movie.java new file mode 100644 index 0000000..9de2ff9 --- /dev/null +++ b/实验四/Movie.java @@ -0,0 +1,23 @@ +public abstract class Movie implements MoviePlayable { + private String title; + private int year; + private double rating; + private String genre; + + public Movie(String title, int year, double rating, String genre) { + this.title = title; + this.year = year; + this.rating = rating; + this.genre = genre; + } + + // 接口方法,留给子类实现 + @Override + public abstract void play(); + + // getter + public String getTitle() { return title; } + public int getYear() { return year; } + public double getRating() { return rating; } + public String getGenre() { return genre; } +} \ No newline at end of file diff --git a/实验四/MovieCrawler.java b/实验四/MovieCrawler.java new file mode 100644 index 0000000..59c8314 --- /dev/null +++ b/实验四/MovieCrawler.java @@ -0,0 +1,74 @@ +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; +import java.util.ArrayList; +import java.util.List; + +public class MovieCrawler extends BaseMovieCrawler { + + private static final String DOUBAN_URL = "https://movie.douban.com/top250?start=0"; + private static final String XIAOHONGSHU_URL = "https://www.xiaohongshu.com"; + private static final String DOUYIN_URL = "https://www.douyin.com"; + + @Override + public List crawl(int limit) { + List list = new ArrayList<>(); + list.addAll(crawlByType(DOUBAN_URL, "douban", limit)); + list.addAll(crawlByType(XIAOHONGSHU_URL, "xiaohongshu", limit)); + list.addAll(crawlByType(DOUYIN_URL, "douyin", limit)); + return list; + } + + private List crawlByType(String url, String type, int limit) { + List res = new ArrayList<>(); + try { + Document doc = Jsoup.connect(url) + .userAgent("Mozilla/5.0") + .timeout(10000) + .get(); + + Elements items = doc.select(".item"); + if (items.isEmpty()) items = doc.select("div"); + + int count = 0; + for (Element e : items) { + if (count >= limit) break; + Movie m = parseMovie(e, type); + if (m != null) { + res.add(m); + count++; + } + } + } catch (Exception ex) { + System.out.println(type + " 抓取失败(反爬保护),已跳过"); + } + return res; + } + + @Override + protected Movie parseMovie(Element element, String type) { + try { + if (type.equals("douban")) { + String title = element.select(".hd .title").first().text(); + double rating = Double.parseDouble(element.select(".rating_num").first().text()); + return new TheatreMovie(title, 2024, rating, "电影", 49.9); + } + + if (type.equals("xiaohongshu")) { + String title = element.select("h2").first().text(); + // 改成你真实的类名 Xiaohongshu + return new XiaohongshuMovie(title, 2024, 9.2, "笔记", "小红书用户"); + } + + if (type.equals("douyin")) { + String title = element.select("h3").first().text(); + // 改成你真实的类名 Douyin + return new DouyinMovie(title, 2024, 9.5, "视频", "100w+"); + } + } catch (Exception e) { + return null; + } + return null; + } +} \ No newline at end of file diff --git a/实验四/MovieCrawlerInterface.java b/实验四/MovieCrawlerInterface.java new file mode 100644 index 0000000..55e7ad2 --- /dev/null +++ b/实验四/MovieCrawlerInterface.java @@ -0,0 +1,5 @@ +import java.util.List; + +public interface MovieCrawlerInterface { + List crawl(int limit); +} diff --git a/实验四/MoviePlayable.java b/实验四/MoviePlayable.java new file mode 100644 index 0000000..3549d76 --- /dev/null +++ b/实验四/MoviePlayable.java @@ -0,0 +1,3 @@ +public interface MoviePlayable { + void play(); +} \ No newline at end of file diff --git a/实验四/TheatreMovie.java b/实验四/TheatreMovie.java new file mode 100644 index 0000000..1e51756 --- /dev/null +++ b/实验四/TheatreMovie.java @@ -0,0 +1,13 @@ +public class TheatreMovie extends Movie { + private double price; + + public TheatreMovie(String title, int year, double rating, String genre, double price) { + super(title, year, rating, genre); + this.price = price; + } + + @Override + public void play() { + System.out.println("院线电影播放:" + getTitle() + ",票价:" + price); + } +} \ No newline at end of file diff --git a/实验四/XiaohongshuMovie.java b/实验四/XiaohongshuMovie.java new file mode 100644 index 0000000..9c26015 --- /dev/null +++ b/实验四/XiaohongshuMovie.java @@ -0,0 +1,13 @@ +public class XiaohongshuMovie extends Movie { + private String author; + + public XiaohongshuMovie(String title, int year, double rating, String genre, String author) { + super(title, year, rating, genre); + this.author = author; + } + + @Override + public void play() { + System.out.println("小红书笔记:" + getTitle() + ",作者:" + author); + } +}