IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 【Spark】岗位数据分析 -> 正文阅读

[大数据]【Spark】岗位数据分析

配置详解

本文是使用Scrapy来获取数据,再使用Spark来进行分析
各版本如下

软件 / 库版本
Pycharm社区版2021.3.3
Python3.8
Pandas1.4.1
Numpy1.22.3
PyMySQL1.0.2
scrapy2.4.1
MySQL5.7
Spark2.0.0

由于社区原因,Scrapy部分不会讲解,只贴代码。

跳转顶部


数据获取

MySQL建表语句

DROP TABLE IF EXISTS `job`;
CREATE TABLE `job` (
  `address` varchar(255) DEFAULT NULL,
  `company` varchar(255) DEFAULT NULL,
  `edu` varchar(255) DEFAULT NULL,
  `jobName` varchar(255) DEFAULT NULL,
  `salary` varchar(255) DEFAULT NULL,
  `size` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

跳转顶部


Settings文件

BOT_NAME = 'job'

SPIDER_MODULES = ['job.spiders']
NEWSPIDER_MODULE = 'job.spiders'

# Crawl responsibly by identifying yourself (and your website) on the user-agent
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.82 Safari/537.36'

# Obey robots.txt rules
ROBOTSTXT_OBEY = False
LOG_LEVEL = 'ERROR'

ITEM_PIPELINES = {
    'job.pipelines.JobPipeline': 300,
}

跳转顶部


主项目代码

import scrapy
import re
import lxml.html
from job.items import JobItem


class TestSpider(scrapy.Spider):
    name = 'Test'
    # allowed_domains = ['baidu.com']
    start_urls = ['https://job001.cn/jobs?keyType=0&keyWord=java']
    basic_url = 'https://job001.cn/jobs?keyType=0&keyWord=java&jobTypeId=&jobType=%E8%81%8C%E4%BD%8D%E7%B1%BB%E5%9E%8B&industry=&industryname=%E8%A1%8C%E4%B8%9A%E7%B1%BB%E5%9E%8B&workId=&workPlace=&salary=&entType=&experience=&education=&entSize=&benefits=&reftime=&workTypeId=&sortField=&pageNo=3&curItem='

    def parse(self, response):
        html = response.text
        selector = lxml.html.fromstring(html)
        maxPage = selector.xpath('//*[@id="pagediv"]/a[11]/text()')[0]
        for num in range(int(maxPage)):
            url = self.basic_url.replace('pageNo=3', f'pageNo={num + 1}')
            yield scrapy.Request(url=url, callback=self.getUrl)

    def getUrl(self, response):
        html = response.text
        selector = lxml.html.fromstring(html)
        hrefList = selector.xpath('//*[@id="infolists"]/div')
        for hrefL in hrefList:
            href = None if len(hrefL.xpath('./div[1]/div[1]/dl/dt/div[1]/a/@href')) == 0 else \
                hrefL.xpath('./div[1]/div[1]/dl/dt/div[1]/a/@href')[0]
            if (href != None):
                url = 'https://job001.cn' + href
                yield scrapy.Request(url=url, callback=self.parsePage)

    def parsePage(self, response):
        item = JobItem()
        page_html = response.text
        selector = lxml.html.fromstring(page_html)
        item['jobName'] = selector.xpath('/html/body/div[14]/div[1]/div[1]/div[1]/h1/text()')[0]
        datas = str(selector.xpath('string(/html/body/div[14]/div[1]/div[1]/div[2])')).replace('\t', '').replace('\n',
                                                                                                                 '').split(
            '·')
        item['address'] = datas[0]
        if (len(datas) == 4):
            item['edu'] = datas[2]
        else:
            item['edu'] = datas[1]

        item['salary'] = str(selector.xpath('/html/body/div[14]/div[1]/div[1]/div[1]/span/text()')[0]).replace('\t',
                                                                                                               '').replace(
            '\n',
            '')
        item['company'] = selector.xpath('/html/body/div[15]/div[2]/div[1]/div/div[2]/a/text()')[0]
        item['size'] = selector.xpath('/html/body/div[15]/div[2]/div[1]/ul/li[3]/text()')[0]
        yield item

跳转顶部


items部分代码

# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html

import scrapy


class JobItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    jobName = scrapy.Field()
    address = scrapy.Field()
    edu = scrapy.Field()
    salary = scrapy.Field()
    company = scrapy.Field()
    size = scrapy.Field()

跳转顶部


pipelines部分代码**

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html


# useful for handling different item types with a single interface
from itemadapter import ItemAdapter
import pymysql


class JobPipeline:
    def process_item(self, item, spider):
        conn = pymysql.connect(host='localhost', port=3306, db='crawler', user='root', password='123456',
                               charset='utf8')
        cursor = conn.cursor()
        sql = """
        insert into job values(%s,%s,%s,%s,%s,%s)
        """
        cursor.execute(sql,
                       (item['address'],
                        item['company'],
                        item['edu'],
                        item['jobName'],
                        item['salary'],
                        item['size']))
        conn.commit()
        return item

跳转顶部


结果展示
在这里插入图片描述

跳转顶部


数据分析

读取数据

    val spark = SparkSession.builder()
      .master("local[6]")
      .appName("job")
      .config("spark.sql.warehouse.dir", "C:/")
      .getOrCreate()
    spark.sparkContext.setLogLevel("ERROR")
    val source = spark.read
      .format("jdbc")
      .option("url", "jdbc:mysql://localhost:3306/crawler")
      .option("dbtable", "job")
      .option("user", "root")
      .option("password", "123456")
      .load()
      .rdd

在这里插入图片描述
我们可以看到薪资的格式,此时我们需要将其格式做一些变化

    val data = source.map(datas => {
      val salary = datas(4)
      val minSalary = if (salary.toString.split("-")(0).contains("面议")) salary
        .toString.split("-")(0).substring(4) else salary.toString.split("-")(0)
      val maxSalary = salary.toString.split("-")(1).substring(0, salary.toString.split("-")(1).length - 1)
      (datas(0).toString, datas(1).toString, datas(2).toString, datas(3).toString, minSalary.toFloat, maxSalary.toFloat, datas(5).toString)
    })

在这里插入图片描述

分析不同学历的平均薪资

    import org.apache.spark.sql.functions._
    import spark.implicits._
    val dataDF = data.toDF("address", "company", "edu", "jobName", "minSalary", "maxSalary", "size")
    //求每个学历的平均估值(最高薪资平均值、最低薪资平均值求平均)
    val eduData = dataDF.select('edu, 'minSalary, 'maxSalary)
      .groupBy('edu)
      .agg(avg("minSalary") as "avgMinSalary", avg("maxSalary") as "avgMaxSalary")
      .withColumn("avgSalary", ('avgMinSalary + 'avgMaxSalary) / 2)
      .select('edu, expr("round(avgSalary,2)") as "avgSalary")
      .sort('avgSalary desc)
      .show()

在这里插入图片描述

跳转顶部


分析不同岗位的平均薪资

    val jobData = dataDF.select('jobName, 'minSalary, 'maxSalary)
      .groupBy('jobName)
      .agg(avg("minSalary") as "avgMinSalary", avg("maxSalary") as "avgMaxSalary")
      .withColumn("avgSalary", ('avgMinSalary + 'avgMaxSalary) / 2)
      .select('jobName, expr("round(avgSalary,2)") as "avgSalary")
      .sort('avgSalary desc)
      .show()

在这里插入图片描述

跳转顶部


分析各公司提供的岗位

    val comData = dataDF.select('company, 'address)
      .groupBy('company)
      .agg(count("address") as "jobNum")
      .sort('jobNum desc)
      .show()

在这里插入图片描述

跳转顶部


  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-05-09 12:46:25  更:2022-05-09 12:50:36 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 23:16:48-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码