爬取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°reefrom=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