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/实验五/CrawlStrategy.java b/实验五/CrawlStrategy.java new file mode 100644 index 0000000..cc2e3e7 --- /dev/null +++ b/实验五/CrawlStrategy.java @@ -0,0 +1,10 @@ +import org.jsoup.nodes.Element; +import java.util.List; + +// 策略接口:所有网站爬取都必须实现这两个方法 +public interface CrawlStrategy { + // 爬取电影 + List crawl(int limit); + // 解析电影元素 + Movie parseMovie(Element element); +} \ No newline at end of file diff --git a/实验五/CrawlerContext.java b/实验五/CrawlerContext.java new file mode 100644 index 0000000..cfe6371 --- /dev/null +++ b/实验五/CrawlerContext.java @@ -0,0 +1,27 @@ +import java.util.ArrayList; +import java.util.List; + +// 上下文:负责管理和执行策略 +public class CrawlerContext { + // 组合多个策略(可同时爬多个网站) + private List strategies = new ArrayList<>(); + + // 添加一个爬取策略 + public void addStrategy(CrawlStrategy strategy) { + strategies.add(strategy); + } + + // 执行所有策略 + public List executeAllCrawl(int limit) { + List result = new ArrayList<>(); + for (CrawlStrategy strategy : strategies) { + result.addAll(strategy.crawl(limit)); + } + return result; + } + + // 清空策略 + public void clearStrategies() { + strategies.clear(); + } +} \ No newline at end of file diff --git a/实验五/DoubanStrategy.java b/实验五/DoubanStrategy.java new file mode 100644 index 0000000..2dff832 --- /dev/null +++ b/实验五/DoubanStrategy.java @@ -0,0 +1,46 @@ +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 DoubanStrategy implements CrawlStrategy { + private static final String URL = "https://movie.douban.com/top250?start=0"; + + @Override + public List crawl(int limit) { + List list = new ArrayList<>(); + try { + Document doc = Jsoup.connect(URL) + .userAgent("Mozilla/5.0") + .timeout(10000) + .get(); + + Elements items = doc.select(".item"); + int count = 0; + for (Element e : items) { + if (count >= limit) break; + Movie m = parseMovie(e); + if (m != null) { + list.add(m); + count++; + } + } + } catch (Exception ex) { + System.out.println("豆瓣抓取失败(反爬保护),已跳过"); + } + return list; + } + + @Override + public Movie parseMovie(Element element) { + try { + 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); + } catch (Exception e) { + return null; + } + } +} 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/实验五/DouyinStrategy.java b/实验五/DouyinStrategy.java new file mode 100644 index 0000000..9c4dfc1 --- /dev/null +++ b/实验五/DouyinStrategy.java @@ -0,0 +1,45 @@ +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 DouyinStrategy implements CrawlStrategy { + private static final String URL = "https://www.douyin.com"; + + @Override + public List crawl(int limit) { + List list = new ArrayList<>(); + try { + Document doc = Jsoup.connect(URL) + .userAgent("Mozilla/5.0") + .timeout(10000) + .get(); + + Elements items = doc.select("div"); + int count = 0; + for (Element e : items) { + if (count >= limit) break; + Movie m = parseMovie(e); + if (m != null) { + list.add(m); + count++; + } + } + } catch (Exception ex) { + System.out.println("抖音抓取失败(反爬保护),已跳过"); + } + return list; + } + + @Override + public Movie parseMovie(Element element) { + try { + String title = element.select("h3").first().text(); + return new DouyinMovie(title, 2024, 9.5, "视频", "100w+"); + } catch (Exception e) { + return null; + } + } +} diff --git a/实验五/Main.java b/实验五/Main.java new file mode 100644 index 0000000..72cf1cf --- /dev/null +++ b/实验五/Main.java @@ -0,0 +1,21 @@ +import java.util.List; + +public class Main { + public static void main(String[] args) { + // 1. 创建上下文 + CrawlerContext context = new CrawlerContext(); + + // 2. 动态添加策略(想爬哪个就加哪个,随时增删) + context.addStrategy(new DoubanStrategy()); + context.addStrategy(new XiaohongshuStrategy()); + context.addStrategy(new DouyinStrategy()); + + // 3. 执行爬取 + List movies = context.executeAllCrawl(2); + + // 4. 多态播放 + for (Movie m : movies) { + 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/实验五/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); + } +} diff --git a/实验五/XiaohongshuStrategy.java b/实验五/XiaohongshuStrategy.java new file mode 100644 index 0000000..1b0242e --- /dev/null +++ b/实验五/XiaohongshuStrategy.java @@ -0,0 +1,45 @@ +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 XiaohongshuStrategy implements CrawlStrategy { + private static final String URL = "https://www.xiaohongshu.com"; + + @Override + public List crawl(int limit) { + List list = new ArrayList<>(); + try { + Document doc = Jsoup.connect(URL) + .userAgent("Mozilla/5.0") + .timeout(10000) + .get(); + + Elements items = doc.select("div"); + int count = 0; + for (Element e : items) { + if (count >= limit) break; + Movie m = parseMovie(e); + if (m != null) { + list.add(m); + count++; + } + } + } catch (Exception ex) { + System.out.println("小红书抓取失败(反爬保护),已跳过"); + } + return list; + } + + @Override + public Movie parseMovie(Element element) { + try { + String title = element.select("h2").first().text(); + return new XiaohongshuMovie(title, 2024, 9.2, "笔记", "小红书用户"); + } catch (Exception e) { + return null; + } + } +} \ No newline at end of file