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