2 changed files with 161 additions and 0 deletions
@ -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<Job> 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<String, Integer> skillFrequency = analyzer.analyzeSkillFrequency(jobs); |
||||
|
|
||||
|
// 分析薪资与经验关系
|
||||
|
Map<String, Double> salaryByExperience = analyzer.analyzeSalaryByExperience(jobs); |
||||
|
|
||||
|
// 分析薪资与学历关系
|
||||
|
Map<String, Double> salaryByEducation = analyzer.analyzeSalaryByEducation(jobs); |
||||
|
|
||||
|
// 分析不同地点薪资水平
|
||||
|
Map<String, Double> salaryByLocation = analyzer.analyzeSalaryByLocation(jobs); |
||||
|
|
||||
|
// 分析薪资分布
|
||||
|
Map<String, Integer> 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所有任务完成!"); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,101 @@ |
|||||
|
package java01; |
||||
|
|
||||
|
import java.util.Map; |
||||
|
|
||||
|
public class ResultDisplay { |
||||
|
|
||||
|
// 控制台输出技能词频统计
|
||||
|
public void displaySkillFrequency(Map<String, Integer> skillFrequency) { |
||||
|
System.out.println("\n=== 技能词频统计 ==="); |
||||
|
System.out.printf("%-20s %s\n", "技能", "出现次数"); |
||||
|
System.out.println("------------------------"); |
||||
|
|
||||
|
int count = 0; |
||||
|
for (Map.Entry<String, Integer> entry : skillFrequency.entrySet()) { |
||||
|
if (count < 20) { // 只显示前20个
|
||||
|
System.out.printf("%-20s %d\n", entry.getKey(), entry.getValue()); |
||||
|
count++; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 控制台输出薪资与经验关系
|
||||
|
public void displaySalaryByExperience(Map<String, Double> salaryByExperience) { |
||||
|
System.out.println("\n=== 薪资与经验关系 ==="); |
||||
|
System.out.printf("%-15s %s\n", "经验", "平均薪资(元)"); |
||||
|
System.out.println("------------------------"); |
||||
|
|
||||
|
for (Map.Entry<String, Double> entry : salaryByExperience.entrySet()) { |
||||
|
System.out.printf("%-15s %.2f\n", entry.getKey(), entry.getValue()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 控制台输出薪资与学历关系
|
||||
|
public void displaySalaryByEducation(Map<String, Double> salaryByEducation) { |
||||
|
System.out.println("\n=== 薪资与学历关系 ==="); |
||||
|
System.out.printf("%-15s %s\n", "学历", "平均薪资(元)"); |
||||
|
System.out.println("------------------------"); |
||||
|
|
||||
|
for (Map.Entry<String, Double> entry : salaryByEducation.entrySet()) { |
||||
|
System.out.printf("%-15s %.2f\n", entry.getKey(), entry.getValue()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 控制台输出不同地点薪资水平
|
||||
|
public void displaySalaryByLocation(Map<String, Double> salaryByLocation) { |
||||
|
System.out.println("\n=== 不同地点薪资水平 ==="); |
||||
|
System.out.printf("%-15s %s\n", "地点", "平均薪资(元)"); |
||||
|
System.out.println("------------------------"); |
||||
|
|
||||
|
for (Map.Entry<String, Double> entry : salaryByLocation.entrySet()) { |
||||
|
System.out.printf("%-15s %.2f\n", entry.getKey(), entry.getValue()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 控制台输出薪资分布
|
||||
|
public void displaySalaryDistribution(Map<String, Integer> salaryDistribution) { |
||||
|
System.out.println("\n=== 薪资分布 ==="); |
||||
|
System.out.printf("%-15s %s\n", "薪资范围", "职位数量"); |
||||
|
System.out.println("------------------------"); |
||||
|
|
||||
|
for (Map.Entry<String, Integer> entry : salaryDistribution.entrySet()) { |
||||
|
System.out.printf("%-15s %d\n", entry.getKey(), entry.getValue()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 生成技能词频柱状图(控制台文本版本)
|
||||
|
public void generateSkillFrequencyChart(Map<String, Integer> skillFrequency, String fileName) { |
||||
|
System.out.println("\n=== 技能词频统计图表 ==="); |
||||
|
int count = 0; |
||||
|
for (Map.Entry<String, Integer> 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<String, Integer> salaryDistribution, String fileName) { |
||||
|
System.out.println("\n=== 薪资分布图表 ==="); |
||||
|
for (Map.Entry<String, Integer> entry : salaryDistribution.entrySet()) { |
||||
|
System.out.printf("%-15s %d\n", entry.getKey(), entry.getValue()); |
||||
|
} |
||||
|
System.out.println("薪资分布图表已生成(文本版本)"); |
||||
|
} |
||||
|
|
||||
|
// 生成薪资与经验关系折线图(控制台文本版本)
|
||||
|
public void generateSalaryByExperienceChart(Map<String, Double> salaryByExperience, String fileName) { |
||||
|
System.out.println("\n=== 薪资与经验关系图表 ==="); |
||||
|
for (Map.Entry<String, Double> entry : salaryByExperience.entrySet()) { |
||||
|
System.out.printf("%-15s %.2f\n", entry.getKey(), entry.getValue()); |
||||
|
} |
||||
|
System.out.println("薪资与经验关系图表已生成(文本版本)"); |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue