其他分享
首页 > 其他分享> > 爬取51job上的职位信息,并做成可视化界面

爬取51job上的职位信息,并做成可视化界面

作者:互联网

爬取51job上的职位信息,并做成可视化界面


前言

找工作时,我们总被各种各样的职位信息搞得眼花缭乱,本项目想要通过爬取51job上的职位信息,来可视化数据,方便我们能横向对比,找到自己心怡的工作。

一、爬取、解析数据

这一步需要爬取数据,然后解析数据,最后保存数据,可以保存为excel文件,也可以保存到数据库中。

1、引入库

import re                            #正则表达式,进行文字匹配
from bs4 import BeautifulSoup        #网页解析,获取数据
import urllib.request,urllib.error   #指定URL,获取网页数据
import xlwt                          #进行excel操作
import sqlite3                       #进行数据库操作

2、利用urllib库里的函数,获取网页信息

因为抓取到的信息是很乱的“大杂烩”,里面既有公司信息,又有工资薪酬,工作时间等等,所以我们需要用正则表达式进行匹配,挑选出不同类别的属性,放在同一个工作岗位下,一个工作岗位有:8个属性分别是:职位名称、公司名称、公司性质、公司链接、工资、工作地点、是否是实习、员工待遇。 str(item)"大杂烩"长这样:
><script type="text/javascript">
>window.__SEARCH_RESULT__ = {"top_ads":[],"auction_ads":[],"market_ads":[],"engine_search_result":[{"type":"engine_search_result","jt":"0","tags":[],"ad_track":"","jobid":"127395071","coid":"2599638","effect":"1","is_special_job":"","job_href":"https:\/\/jobs.51job.com\/guangzhou-thq\/127395071.html?s=sou_sou_soulb&t=0","job_name":"软件工程师(C++\/Python\/go\/lua)","job_title":"软件工程师(C++\/Python\/go\/lua)","company_href":"https:\/\/jobs.51job.com\/all\/co2599638.html","company_name":"广州巨辰信息科技有限公司","providesalary_text":"0.8-1.3万\/月","workarea":"030204","workarea_text":"广州-天河区","updatedate":"04-05","iscommunicate":"","companytype_text":"民营公司","degreefrom":"5","workyear":"4","issuedate":"2021-04-05 04:01:58","isFromXyz":"","isIntern":"0","jobwelf":"五险一金 员工旅游 专业培训 绩效奖金 带薪年假 节日福利 全勤奖 梦想基金 咖啡好茶 周末双休","jobwelf_list":["五险一金","员工旅游","专业培训","绩效奖金","带薪年假","节日福利","全勤奖","梦想基金","咖啡好茶","周末双休"],"attribute_text":["广州-天河区","2年经验","大专","招1人"],"companysize_text":"50-150人","companyind_text":"通信\/电信运营、增值服务","adid":""},{"type":"engine_search_result","jt":"0","tags":[],"ad_track":"","jobid":"130658435","coid":"3645991","effect":"1","is_special_job":"","job_href":"https:\/\/jobs.51job.com\/guangzhou-hpq\/130658435.html?s=sou_sou_soulb&t=0","job_name":"Python后端开发工程师","job_title":"Python后端开发工程师","company_href":"https:\/\/jobs.51job.com\/all\/co3645991.html","company_name":"网易集团","providesalary_text":"1.5-3万\/月","workarea":"030206","workarea_text":"广州-黄埔区","updatedate":"04-05","iscommunicate":"","companytype_text":"上市公司","degreefrom":"6","workyear":"5","issuedate":"2021-04-05 07:08:27","isFromXyz":"","isIntern":"0","jobwelf":"五险一金 餐饮补贴 免费班车 年终奖金 绩效奖金","jobwelf_list":["五险一金","餐饮补贴","免费班车","年终奖金","绩效奖金"],"attribute_text":["广州-黄埔区","3-4年经验","本科","招若干人"],"companysize_text":"10000人以上","companyind_text":"网络游戏","adid":""},{"type":"engine_search_result","jt":"0","tags":[],"ad_track":"","jobid":"130658909","coid":"3844589","effect":"1","is_special_job":"","job_href":"https:\/\/jobs.51job.com\/guangzhou-thq\/130658909.html?s=sou_sou_soulb&t=0","job_name":"Python开发工程师","job_title":"Python开发工程师","company_href":"https:\/\/jobs.51job.com\/all\/co3844589.html","company_name":"广州迪奥信息
......
</script>
def getData(baseurl):
    datalist=[]
    for i in range(1,21):  #爬取20页,每页有50个职位信息,所以总共是1000个职位信息
        url=baseurl+str(i)+".html?lang=c&postchannel=0000&workyear=99&cotype=99&degreefrom=99&jobterm=99&companysize=99&ord_field=0&dibiaoid=0&line=&welfare="            #根据网页翻页后,网页的变化,写出网址
        html=askURL(url)
        #逐一解析数据
        #用html解析器,把文档存放在内存中
        soup=BeautifulSoup(html,"html.parser") #利用
        for i,item in enumerate(soup.find_all('script', type='text/javascript')):
            data=[];

            data2=[]
            if i==2:
                item=str(item);
                #print(item)

                #找到工作名称
                jobname=re.findall(findjobname,item)
                #print(len(jobname))
                data.append(jobname)

                #招聘公司名称
                companyname=re.findall(findcompanyname,item)
                #print(len(companyname))
                data.append(companyname)


                #公司性质
                compInf=re.findall(findcompInf,item)
                #print(len(compInf))
                data.append(compInf)

                #招聘公司链接
                complink=re.findall(findcomplink,item)
                #print(len(complink))
                data.append(complink)

                #工资薪酬
                salary=re.findall(findsalary,item)
                #print(len(salary))
                data.append(salary)

                #工作地点
                workplace=re.findall(findworkplace,item)
                #print(len(workplace))
                data.append(workplace)

                #是否是实习
                isIntern=re.findall(findisIntern,item)
                for i in range(len(isIntern)):
                    if isIntern[i]=="0":isIntern[i]="否"
                    else:isIntern[i]="是"
                #print(isIntern)
                data.append(isIntern)

                #福利待遇
                wel=re.findall(findwel,item)
                #print(len(wel))
                data.append(wel)
                #print(data)


                for i in range(len(data[0])):
                    data1=[]
                    for j in range(len(data)):
                        #print(data[j][i])
                        data1.append(data[j][i])
                    #print(data1)
                    data2.append(data1)
                datalist+=data2

                #print("data2:行=%d,列=%d"%(len(data2),len(data2[0])))
               #print(data2)


    #print("datalist:行=%d,列=%d"%(len(datalist),len(datalist[0])))
    return datalist

def askURL(url):
    head={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36"}
    #建立请求
    request=urllib.request.Request(headers=head,url=url)
    try:
        #发送请求
        response=urllib.request.urlopen(request)
        #将爬取下来地信息保存到html
        html=response.read().decode("gbk");
        #html=response.read()


        #print(html)
    except urllib.error.URLError as e:
        if hasattr(e, "code"):
            print(e, code);
        if hasattr(e, "reason"):
            print(e.reason);
    return html

爬取出来的数据(datalist里面的内容):

[[‘软件工程师(C++\/Python\/go\/lua)’, ‘广州巨辰信息科技有限公司’, ‘民营公司’, ‘https:\/\/jobs.51job.com\/all\/co2599638.html’, ‘0.8-1.3万\/月’, ‘广州-天河区’, ‘否’, ‘五险一金 员工旅游 专业培训 绩效奖金 带薪年假 节日福利 全勤奖 梦想基金 咖啡好茶 周末双休’], [‘Python后端开发工程师’, ‘网易集团’, ‘上市公司’, ‘https:\/\/jobs.51job.com\/all\/co3645991.html’, ‘1.5-3万\/月’, ‘广州-黄埔区’, ‘否’, ‘五险一金 餐饮补贴 免费班车 年终奖金 绩效奖金’], [‘Python开发工程师’, ‘广州迪奥信息科技有限公司’, ‘民营公司’, ‘https:\/\/jobs.51job.com\/all\/co3844589.html’, ‘0.7-1万\/月’, ‘广州-天河区’, ‘否’, ‘五险一金 员工旅游 绩效奖金 年终奖金 住房补贴 节日福利 定期体检 带薪年假’], [‘资深开发工程师(Java\/Python)’, ‘广州翰智软件有限公司’, ‘民营公司’, https:\/\/jobs.51job.com\/all\/co2886918.html’, ‘1-1.8万\/月’, ‘广州’, ‘否’, ‘五险一金 餐饮补贴 定期体检 通讯补贴 专业培训 员工旅游 交通补贴 绩效奖金 股票期权 年终奖金’], [‘Python开发工程师’, ‘爱立信信息技术服务(中国)有限公司’, ‘外资(欧美)’, ‘https:\/\/jobs.51job.com\/all\/co1723795.html’, ‘0.8-1.2万\/月’, ‘广州’, ‘否’, ‘专业培训 丰富集体活动 五险一金 补充医疗保险 定期体检 弹性工作 绩效奖金’], [‘Python开发工程师’, ‘广州多益网络股份有限公司’, ‘民营公司’, ‘https:\/\/jobs.51job.com\/all\/co2063629.html’, ‘0.9-2万\/月’, ‘广州-黄埔区’, ‘否’, ‘互联网百强’],…


二、保存数据

1.保存在excel中

#保存数据在excel中
def saveData(savepath,datalist):
    print("save...")
    book=xlwt.Workbook(encoding="utf-8",style_compression=0)
    sheet=book.add_sheet("job51",cell_overwrite_ok=True);
    #jobname,companyname,compInf,complink,salary,workplace,IsIntern,wel)
    firstcol=("职位名称","公司名字","公司性质","公司链接","月薪","工作地点","是否是实习","待遇")
    for i in range(8):
        sheet.write(0,i,firstcol[i])
    for i in range(0,1000):
        #print("第%d条"%(i+1))
        data=datalist[i]
        for j in range(8):
            sheet.write(i+1,j,data[j])
    book.save(savepath)

调用的时候:

  #保存在excel中
  savapath="job51.xls"          
  saveData(savapath,datalist);

生成的job51.xls长这样:
在这里插入图片描述


2、保存在sqlite数据库中

#保存数据在数据库中
def saveData2DB(datalist,dbpath):
    init_db(dbpath)
    conn=sqlite3.connect(dbpath)
    cur=conn.cursor()
    #print(datalist)
    for data in datalist:
        for index in range(len(data)):
            data[index]='"'+data[index]+'"'
        sql = '''
                insert into job51(
                jobname,companyname,compInf,complink,month_salary,workplace,IsIntern,wel)         
                values(%s)''' % (",".join(data))
        #print(sql)
        cur.execute(sql)
        conn.commit()
    cur.close()
    conn.close()



#创建一个数据库,并且填写好一个排各个类别
def init_db(dbpath):
    sql='''
        create table job51
    (
    id integer primary key autoincrement,
    jobname text,
    companyname  text,
    compInf text,
    complink text,
    salary text ,
    workplace text,
    IsIntern text ,
    wel text
    );
    
    '''
    conn=sqlite3.connect(dbpath)
    cur=conn.cursor()
    cur.execute(sql)
    conn.commit()
    cur.close()
    conn.close()

调用时:

    #保存在数据库中
    dbpath="job51.db"
    saveData2DB(datalist,dbpath)

生成的数据库长这样:在这里插入图片描述


三、制作网页,实现数据可视化

这里主要是通过,在网络在网上下载一个网络模板,再进行改造,即填充属于自己的内容。
这里会用到flask,echarts,wordcloud的相关知识。

1、Flask

用于网站开发,是一个web框架,它的作用主要是为了开发web应用程序。那么我们首先来了解下Web应用程序: 网络有两个端,一个是客户端,一个是服务端,客户端向服务器发送请求,服务器响应这些请求,至于是如何请求,如何响应,都写在了flask框架里,我们只需调用,就ok了。 pycharm 生成的flask框架如下图所示:

在这里插入图片描述
运行的话,就会出现一个网址(下图蓝色),点击就能看见Hello World 了:
在这里插入图片描述
所以我们建立一个中枢(flask架构的app.html),连接着列表,echarts 和词云网页

from flask import Flask,render_template
import sqlite3
app = Flask(__name__)


@app.route('/')
def index():
    return render_template("home.html")

@app.route("/home")
def home():
    # return render_template("index.html")
    return index()

@app.route('/worklist')
def worklist():
    datalist=[]
    conn=sqlite3.connect("job51.db")
    cur=conn.cursor()
    sql="select * from  job51"
    data=cur.execute(sql)
    for item in data:
        datalist.append(item)
    cur.close()
    conn.close()
    return render_template("worklist.html",worklists=datalist)     #页面接参数的方式,直接在后面加逗号

@app.route('/salary')
def salary():
    salary=[]
    num=[]
    con=sqlite3.connect("job51.db")
    cur=con.cursor()
    sql="select month_salary,count(month_salary) from job51 group by month_salary"
    data=cur.execute(sql)

    for item in data:
        salary.append(item[0])
        num.append(item[1])
    #print(salary[0])
    #print(len(num))
    cur.close()
    con.close()
    # salary=['apple','lemon','orange','peach','banana','grape','mango']
    # num=[300,400,350,200,109,120,470]
    return render_template("salary.html",salary=salary,num=num)

@app.route('/wordcloud')
def word():
    return render_template("wordcloud.html")

@app.route('/team')
def team():
    return render_template("team.html")


if __name__ == '__main__':
    app.run()

主页(home.html)长这样:
在这里插入图片描述


2、echarts

建议直接去官网,5分钟上手echarts
echarts是一个能让数据变成图标展示的工具,只需要在网站上下载你需要的图标,然后替换成我们的数据就行。我们是用工资薪酬作为横坐标,数目作为纵坐标,生成了一个柱状图。

生成的界面如下:
在这里插入图片描述


3、generate wordcloud

一个统计词云出现频率,并且以大小显示出来的,词越大,说明出现频率越大。

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("job51.db")
cur=con.cursor()
sql="select jobname from job51"
data=cur.execute(sql)
text=""
for item in data:
    text=text+item[0]
cur.close()
con.close()

#分词
cut=jieba.cut(text)
string=' '.join(cut)
# print(len(string))

img=Image.open("static/assets/img/tree.jpg")
img_array=np.array(img)   #将图片转换为数组
wc=WordCloud(
    background_color='white',
    mask=img_array,
    font_path='simkai.ttf'     #你这台电脑的字体所在位置:C:\Windows\Fonts

)
wc.generate_from_text(string)    #词云生成函数,参数必须是切好的词


#绘制图片
fig=plt.figure(1)
plt.imshow(wc)
plt.axis("off")  #是否显示坐标轴

plt.show() #显示生成的词云图片
plt.savefig("static/assets/img/job.jpg") #保存词云图片到

原来的树和生成的词云树长这样,(词会填充在非背景颜色上):
在这里插入图片描述
在这里插入图片描述


4、 总结

笔记写得惨不忍睹,呜呜呜。。。 这次只是做了一个很简单的框架,网页也没有美感,做个记录,方便以后需要用的时候,快速入门,等下把这个项目工程文件上传,有需要的可以下载。奥里给!

标签:text,51job,爬取,item,job,html,可视化,print,data
来源: https://blog.csdn.net/selinaliujunlan/article/details/115437386