• Python爬虫大作业+数据可视化分析(抓取python职位)


    目录

    一、抓取并解析数据

    1.导入相关库

    2、获取网页信息

    3.数据清洗

    4.爬取结果:

    ??二、保存数据

    1.保存到excel中

    2.保存到数据库中

    ?

    ?3.调用

    三、使用flask,实现可视化

    1.主函数

    2.可视化界面:

    2.1职位信息展示+分页

    2.2使用echars制作图标?

    2.3导入地图?

    ?2.4制作词云

    ?三.总结


    一、获取数据

    运用正则表达式,找到相对应的数据,然后对数据进行清洗,最后保存数据,保存为excel文件和保存到数据库中。(这里用的是sqlite数据库)

    1.导入相关库

    import re  # 正则表达式,进行文字匹配
    from urllib.request import Request
    from urllib.request import urlopen  # 制定URL,获取网页数据
    from urllib.error import URLError as error
    import json
    import xlwt
    import sqlite3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2、获取网页信息

    爬取到的信息是很多,需要用正则表达式进行匹配,一个工作岗位有:8个属性,我只爬取职位名称、公司名称、公司链接、工资、工作地点、是否是实习、员工待遇。

    def main():
        baseurl = "https://search.51job.com/list/000000,000000,0000,00,9,99,python,2,{}.html?lang=c&postchannel=0000&workyear=99&cotype=99°reefrom=99&jobterm=99&companysize=99&ord_field=0&dibiaoid=0&line=&welfare="
        # 1.爬取网页
        datalist = getData(baseurl)
        savepath = "51job.xls"
        jobpath = "newjob.db"
        # 保存数据到表格
        saveData(datalist, savepath)
        # 保存数据到数据库
        saveData2DB(datalist, jobpath)
    
    
    # 爬取网页
    def getData(baseurl):
        datalist = []
        for page in range(0, 30):
            url1 = baseurl.format(page + 1)
            html = askURL(url1)  # 保存获取到的网页源码
            # 2.逐一解析数据
            html_data = re.findall('window.__SEARCH_RESULT__ =(.*?)', html, re.S)
            html_data = ''.join(html_data)
            infodict = json.loads(html_data)  # 将str类型的数据转换为dict类型
            engine_jds = infodict['engine_jds']
            for item in engine_jds:
                data = []
                job_href = item["job_href"]  # 工作链接
                name = item['job_name']
    
                temp1 = re.sub('	', '', name)
                # 去掉括号中的内容,英文的括号要加反斜杠
                temp2 = re.sub('(.*?)', '', temp1)
                # 去掉括号中的内容,中文括号
                job_name = re.sub('(.*?)', '', temp2)
    
                job_company = item['company_name']
                job_salary1 = item['providesalary_text']
                if job_salary1:
                    job_salary = get_avgsalary(job_salary1)
                else:
                    job_salary = ""
                area = item["workarea_text"]  # 工作地点
                newarea = re.findall('(.*?)-', area, re.S)
                job_area = ''.join(newarea)
                demand = item['attribute_text'][1:]
                job_requirements = ' '.join(demand)
                if job_requirements.find(' ') != -1:
                    job_experience, job_education = job_requirements.split(' ')
                else:
                    job_experience = job_requirements
                job_fuli = item['jobwelf'] if item['jobwelf'] else '无'
                if job_salary == "" or job_area == "" or job_education == "":
                    continue
                else:
                    data.append(job_href)
                    data.append(job_name)
                    data.append(job_company)
                    data.append(job_salary)
                    data.append(job_area)
                    # data.append(job_requirements)
                    data.append(job_experience)
                    data.append(job_education)
                    data.append(job_fuli)
                    datalist.append(data)
            # print(datalist)
        return datalist
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65

    3.数据清洗

    主要对薪资进行清洗,统一以万/月为单位,并取区间平均值。

    # 对薪资进行数据清洗
    def get_avgsalary(salary):
        global avg_salary
        if '-' in salary:  # 针对10-20千/月或者10-20万/年的情况,包含-
            low_salary = re.findall(re.compile('(d*.?d+)'), salary)[0]
            high_salary = re.findall(re.compile('(d?.?d+)'), salary)[1]
            avg_salary = (float(low_salary) + float(high_salary)) / 2
            avg_salary = ('%.2f' % avg_salary)
            if u'万' in salary and u'年' in salary:  # 单位统一成万/月的形式
                avg_salary = float(avg_salary) / 12
                avg_salary = ('%.2f' % avg_salary)  # 保留两位小数
            elif u'千' in salary and u'月' in salary:
                avg_salary = float(avg_salary) / 10
        else:  # 针对20万以上/年和100元/天这种情况,不包含-,取最低工资,没有最高工资
            avg_salary = re.findall(re.compile('(d*.?d+)'), salary)[0]
            if u'万' in salary and u'年' in salary:  # 单位统一成万/月的形式
                avg_salary = float(avg_salary) / 12
                avg_salary = ('%.2f' % avg_salary)
            elif u'千' in salary and u'月' in salary:
                avg_salary = float(avg_salary) / 10
            elif u'元' in salary and u'天' in salary:
                avg_salary = float(avg_salary) / 10000 * 21  # 每月工作日21天
    
        avg_salary = str(avg_salary) + '万/月'  # 统一薪资格式
        return avg_salary
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    4.爬取结果:

    二、保存数据

    1.保存到excel中

    def saveData(datalist, savepath):
        print("sava....")
        book = xlwt.Workbook(encoding="utf-8", style_compression=0)  # 创建work对象
        sheet = book.add_sheet('python', cell_overwrite_ok=True)  # 创建工作表
        col = ("工作链接", "工作名称", "公司", "薪资", "工作地区", "工作经验", "学历", "员工福利")
        for i in range(0, 8):
            sheet.write(0, i, col[i])  # 列名
        for i in range(0, 1000):
            # print("第%d条" %(i+1))
            data = datalist[i]
            for j in range(0, 8):
                sheet.write(i + 1, j, data[j])  # 数据
    
        book.save(savepath)  # 保存数据
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    结果显示:

    2.保存到数据库中

    # 创建数据表 (表名为newjob)
    def init_job(jobpath):
        sql = '''
            create table newjob
            (
            id integer primary key autoincrement,
            job_href text,
            job_name varchar,
            job_company varchar,
            job_salary text ,
            job_area varchar ,
            job_experience text,
            job_education text,
            job_fuli text
            )
    
        '''  
        conn = sqlite3.connect(jobpath)
        cursor = conn.cursor()
        cursor.execute(sql)
        conn.commit()
        conn.close()
    
    #将数据保存到数据库中
    def saveData2DB(datalist, jobpath):
        init_job(jobpath)
        conn = sqlite3.connect(jobpath)
        cur = conn.cursor()
    
        for data in datalist:
            for index in range(len(data)):
                data[index] = '"' + str(data[index]) + '"'
            sql = '''
                    insert into newjob (
                    job_href,job_name,job_company,job_salary,job_area,job_experience,job_education,job_fuli) 
                    values(%s)''' % ",".join(data)
            # print(sql)
            cur.execute(sql)
            conn.commit()
        cur.close()
        conn.close()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    3.调用

    在main函数中

        # 保存数据到表格
        saveData(datalist, savepath)
        # 保存数据到数据库
        saveData2DB(datalist, jobpath)
    
    • 1
    • 2
    • 3
    • 4

    三、使用flask,实现可视化

    1.主函数

    实现绘图、分词、连接数据库导入数据、制作词语等

    import jieba  # 分词作用
    from matplotlib import pyplot as plt  # 绘图作用,数据可视化
    from wordcloud import WordCloud  # 词云
    from PIL import Image  # 图片处理
    import numpy as np  # 矩阵运算
    import sqlite3  # 数据库
    
    # 准备词云所需要的词
    con = sqlite3.connect("newjob.db")
    cur = con.cursor()
    sql = "select job_name from newjob"
    data = cur.execute(sql)
    test = ""
    for item in data:
        test = test + item[0]
    # print(test)
    cur.close()
    con.close()
    
    # 分词
    cut = jieba.cut(test)
    string = " ".join(cut)
    print(len(string))
    
    img = Image.open(r'staticassetsimgdemo.png')  # 打开图片
    img_array = np.array(img)  # 将图片转化为二维数组
    wc = WordCloud(
        background_color="white",
        mask=img_array,
        font_path="msyh.ttc"  # 字体所在位置  c:windowsonts
    )
    wc.generate_from_text(string)
    
    # 绘制图片
    fip = plt.figure(1)
    plt.imshow(wc)
    plt.axis("off")  # 是否显示坐标轴
    # plt.show()  #显示生成的词云图片
    
    #输出词云图片到文件
    plt.savefig(r'staticassetsimgdemo1.jpg')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    2.可视化界面:

    2.1职位信息展示+分页

    2.2使用echars制作图标

    2.3导入地图

    2.4制作词云

    import jieba  # 分词作用
    from matplotlib import pyplot as plt  # 绘图作用,数据可视化
    from wordcloud import WordCloud  # 词云
    from PIL import Image  # 图片处理
    import numpy as np  # 矩阵运算
    import sqlite3  # 数据库
    
    # 准备词云所需要的词
    con = sqlite3.connect("newjob.db")
    cur = con.cursor()
    sql = "select job_name from newjob"
    data = cur.execute(sql)
    test = ""
    for item in data:
        test = test + item[0]
    # print(test)
    cur.close()
    con.close()
    
    # 分词
    cut = jieba.cut(test)
    string = " ".join(cut)
    print(len(string))
    
    img = Image.open(r'staticassetsimgdemo.png')  # 打开图片
    img_array = np.array(img)  # 将图片转化为二维数组
    wc = WordCloud(
        background_color="white",
        mask=img_array,
        font_path="msyh.ttc"  # 字体所在位置  c:windowsonts
    )
    wc.generate_from_text(string)
    
    # 绘制图片
    fip = plt.figure(1)
    plt.imshow(wc)
    plt.axis("off")  # 是否显示坐标轴
    # plt.show()  #显示生成的词云图片
    
    #输出词云图片到文件
    plt.savefig(r'staticassetsimgdemo1.jpg')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    三.总结

    第一次写项目总结,笔记还不太完善,只是做了一个很简单的框架,简单记录一下!(需要完整项目工程文件,可以私信或留言)

    先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦

  • 相关阅读:
    设计模式-享元模式
    算法|每日一题|只出现一次的数字Ⅱ|位运算
    fpga内嵌逻辑分析仪使用方法
    干掉进程:以一种简易友好的方式干掉进程 - Fkill
    已知 list 数组请写出一段代码,实现功能: 数组内type 相同的元素只保留 votes 最大的元素,并且元素需要按照 votes 从大到小排序。
    String(一)———了解编码
    阿里首席架构师谈微服务:入门到实战架构
    开源好用的所见即所得(WYSIWYG)编辑器:Editor.js
    天马行空的超级炫酷旋转图片-前端
    Linux权限管理— sudo授权
  • 原文地址:https://blog.csdn.net/m0_54861649/article/details/126113938