diff --git a/project/Main.java b/project/Main.java new file mode 100644 index 0000000..c66d452 --- /dev/null +++ b/project/Main.java @@ -0,0 +1,60 @@ +package java01; + +import java.util.List; +import java.util.Map; + +public class Main { + public static void main(String[] args) { + // 1. 初始化爬虫 + JobCrawler crawler = new JobCrawler(); + + // 2. 爬取数据 + System.out.println("开始爬取招聘数据..."); + List jobs = crawler.crawlJobs("Java", 3); // 爬取3页数据 + System.out.println("爬取完成,共获取 " + jobs.size() + " 条职位信息"); + + // 3. 数据清洗 + DataCleaner cleaner = new DataCleaner(); + jobs = cleaner.cleanJobs(jobs); + System.out.println("数据清洗完成"); + + // 4. 数据存储 + DataStorage storage = new DataStorage(); + storage.writeJobsToCSV(jobs, "jobs.csv"); + + // 5. 数据分析 + DataAnalyzer analyzer = new DataAnalyzer(); + + // 分析技能词频 + Map skillFrequency = analyzer.analyzeSkillFrequency(jobs); + + // 分析薪资与经验关系 + Map salaryByExperience = analyzer.analyzeSalaryByExperience(jobs); + + // 分析薪资与学历关系 + Map salaryByEducation = analyzer.analyzeSalaryByEducation(jobs); + + // 分析不同地点薪资水平 + Map salaryByLocation = analyzer.analyzeSalaryByLocation(jobs); + + // 分析薪资分布 + Map salaryDistribution = analyzer.analyzeSalaryDistribution(jobs); + + // 6. 结果展示 + ResultDisplay display = new ResultDisplay(); + + // 控制台输出 + display.displaySkillFrequency(skillFrequency); + display.displaySalaryByExperience(salaryByExperience); + display.displaySalaryByEducation(salaryByEducation); + display.displaySalaryByLocation(salaryByLocation); + display.displaySalaryDistribution(salaryDistribution); + + // 生成图表 + display.generateSkillFrequencyChart(skillFrequency, "skill_frequency.png"); + display.generateSalaryDistributionChart(salaryDistribution, "salary_distribution.png"); + display.generateSalaryByExperienceChart(salaryByExperience, "salary_by_experience.png"); + + System.out.println("\n所有任务完成!"); + } +} \ No newline at end of file diff --git a/project/ResultDisplay.java b/project/ResultDisplay.java new file mode 100644 index 0000000..2e716ba --- /dev/null +++ b/project/ResultDisplay.java @@ -0,0 +1,101 @@ +package java01; + +import java.util.Map; + +public class ResultDisplay { + + // 控制台输出技能词频统计 + public void displaySkillFrequency(Map skillFrequency) { + System.out.println("\n=== 技能词频统计 ==="); + System.out.printf("%-20s %s\n", "技能", "出现次数"); + System.out.println("------------------------"); + + int count = 0; + for (Map.Entry entry : skillFrequency.entrySet()) { + if (count < 20) { // 只显示前20个 + System.out.printf("%-20s %d\n", entry.getKey(), entry.getValue()); + count++; + } + } + } + + // 控制台输出薪资与经验关系 + public void displaySalaryByExperience(Map salaryByExperience) { + System.out.println("\n=== 薪资与经验关系 ==="); + System.out.printf("%-15s %s\n", "经验", "平均薪资(元)"); + System.out.println("------------------------"); + + for (Map.Entry entry : salaryByExperience.entrySet()) { + System.out.printf("%-15s %.2f\n", entry.getKey(), entry.getValue()); + } + } + + // 控制台输出薪资与学历关系 + public void displaySalaryByEducation(Map salaryByEducation) { + System.out.println("\n=== 薪资与学历关系 ==="); + System.out.printf("%-15s %s\n", "学历", "平均薪资(元)"); + System.out.println("------------------------"); + + for (Map.Entry entry : salaryByEducation.entrySet()) { + System.out.printf("%-15s %.2f\n", entry.getKey(), entry.getValue()); + } + } + + // 控制台输出不同地点薪资水平 + public void displaySalaryByLocation(Map salaryByLocation) { + System.out.println("\n=== 不同地点薪资水平 ==="); + System.out.printf("%-15s %s\n", "地点", "平均薪资(元)"); + System.out.println("------------------------"); + + for (Map.Entry entry : salaryByLocation.entrySet()) { + System.out.printf("%-15s %.2f\n", entry.getKey(), entry.getValue()); + } + } + + // 控制台输出薪资分布 + public void displaySalaryDistribution(Map salaryDistribution) { + System.out.println("\n=== 薪资分布 ==="); + System.out.printf("%-15s %s\n", "薪资范围", "职位数量"); + System.out.println("------------------------"); + + for (Map.Entry entry : salaryDistribution.entrySet()) { + System.out.printf("%-15s %d\n", entry.getKey(), entry.getValue()); + } + } + + // 生成技能词频柱状图(控制台文本版本) + public void generateSkillFrequencyChart(Map skillFrequency, String fileName) { + System.out.println("\n=== 技能词频统计图表 ==="); + int count = 0; + for (Map.Entry entry : skillFrequency.entrySet()) { + if (count < 10) { + System.out.printf("%-20s ", entry.getKey()); + // 用星号表示频率 + for (int i = 0; i < Math.min(entry.getValue(), 50); i++) { + System.out.print("*"); + } + System.out.println(" " + entry.getValue()); + count++; + } + } + System.out.println("技能词频图表已生成(文本版本)"); + } + + // 生成薪资分布饼图(控制台文本版本) + public void generateSalaryDistributionChart(Map salaryDistribution, String fileName) { + System.out.println("\n=== 薪资分布图表 ==="); + for (Map.Entry entry : salaryDistribution.entrySet()) { + System.out.printf("%-15s %d\n", entry.getKey(), entry.getValue()); + } + System.out.println("薪资分布图表已生成(文本版本)"); + } + + // 生成薪资与经验关系折线图(控制台文本版本) + public void generateSalaryByExperienceChart(Map salaryByExperience, String fileName) { + System.out.println("\n=== 薪资与经验关系图表 ==="); + for (Map.Entry entry : salaryByExperience.entrySet()) { + System.out.printf("%-15s %.2f\n", entry.getKey(), entry.getValue()); + } + System.out.println("薪资与经验关系图表已生成(文本版本)"); + } +} \ No newline at end of file