[爬虫]python根据职位或者公司关键字爬取某招聘网站招聘数据并存储到数据库和exeal中


 目录

1、实现功能

2、运用库

3、设计逻辑

3.1 网页循环爬取并分析

3.2 职位数据分析并输出图片

3.3 合并csv为同一个exeal表格

4、代码分析

4.1 爬取网页并解析

4.1.1 定义URL函数,进行url拼接,获取URL

4.1.2 定义data、以及分析数据所需要的列表、变量

4.1.3 创建py相对路劲下的data文件夹

4.1.4 打开csv文件,并写入表头

4.1.5 根据输入数据的data创建数据库的表名

4.1.6 链接数据库,写入数据库表头

4.1.7 爬取数据并解析

4.2 数据存储

4.3 数据分析

4.3.1 薪资分析

4.3.2 招聘地区、经验要求、学历要求分析

4.4 根据数据分析保存的csv输出柱形图、扇形图

4.5 将输出在同一文件价的csv文件合并为同一个exeal

4.6 根据爬取到的网址再次爬取岗位要求、岗位职责等信息

5、完整代码

5.1 主网页爬取完整代码

5.2 职位详情网页爬取完整代码

5.3 职位数据分析输出扇形图、柱形图完整代码

5.4 根据岗位职责的TXT文件分析输出词云

5.5 合并多个csv文件为同一个exeal表完整代码

6、运行效果

6.1 C语言关键字保存的csv

6.1.1 主要数据csv

6.1.2 地区分析scv

6.1.3 经验要求csv

6.1.4 学历要求csv

6.2 C语言关键字保存的数据库

6.3 C语言关键字分析得到的分析图

6.4 C语言关键字分析岗位职责TXT文件得到的词云图

6.5 C语言关键字分析合并csv得到的exeal

 


1、实现功能

1.1数据爬取:能对前程无忧的招聘数据进行增量爬取,输入岗位或者公司名,输出该岗位或公司的招聘数量、平均薪资、技能要求、岗位职责等;

1.2数据分析及可视化:主要为对工作城市、学历要求、招聘经验、薪资的简单统计分析并输出为csv文件、txt文件,并根据csv的数据得到柱形图,扇形图,且保存图片到本地,以及根据岗位要求数据输出词云;

1.3数据存储:将爬取的数据存储在以爬取关键词命名的新文件中,存储为csv格式,最后将所有分析的csv文件保存到一个exeal表中,并将主要数据存储到mysql数据库中。

2、运用库

 1 #单网页爬取运用库
 2 import requests# 模拟请求 post get
 3 from xpinyin import Pinyin # 将中文输出为拼音
 4 import pprint # 格式化输出模块
 5 import os # 操作文件和目录
 6 import re # 正则表达式模块 内置
 7 import json
 8 import csv # 输出csv的库
 9 import pymysql # 数据库
10 import time # 计算机内部时间库
11 #单网页爬取_职位详情运用库
12 import requests# 模拟请求 post get
13 import time
14 import parsel # 数据解析模块  包含css xpath
15 import pandas as pd # 数据类型和分析工具库
16 #词云分析运用库
17 import re # 正则表达式库
18 import matplotlib.pyplot as plt # 图像展示库
19 import collections # 词频统计库
20 import numpy as np # numpy数据处理库
21 from PIL import Image # 图像处理库
22 import jieba # 结巴分词
23 import wordcloud # 词云展示库
24 #画图运用库
25 import pandas as pd
26 import matplotlib.pyplot as plt

3、设计逻辑

3.1 网页循环爬取并分析

3.2 职位数据分析并输出图片

3.3 合并csv为同一个exeal表格

4、代码分析

4.1 爬取网页并解析

4.1.1 定义URL函数,进行url拼接,获取URL

        此功能能根据输入的检索词data,页码i自动拼接url。我们访问的招聘网站为前程无忧,可以根据关键字data,循环的地址i,获取拼接url地址。如URL为:

https://search.51job.com/list/000000,000000,0000,00,9,99,+,2,1.html?lang=c&postchannel=0000&workyear=99&cotype=99°reefrom=99&jobterm=99&companysize=99&ord_field=0&dibiaoid=0&line=&welfare=https://search.51job.com/list/000000,000000,0000,00,9,99,+,2,1.html?lang=c&postchannel=0000&workyear=99&cotype=99°reefrom=99&jobterm=99&companysize=99&ord_field=0&dibiaoid=0&line=&welfare= https://search.51job.com/list/000000,000000,0000,00,9,99,+,2,1.html?lang=c&postchannel=0000&workyear=99&cotype=99°reefrom=99&jobterm=99&companysize=99&ord_field=0&dibiaoid=0&line=&welfare=

其中:url由以下字符串拼接而成

url1:https://search.51job.com/list/000000,000000,0000,00,9,99

data:#获取需要检索的关键字变量,如大数据、python

url2: ,2, #请求数据1,这里保持不变

rul_yema: #代表请求的页码

url3: .html?lang=c&postchannel=0000&workyear=99&cotype=99&degreefrom=99&jobterm=99&companysize=99&ord_field=0&dibiaoid=0&line=&welfare=

  #代表其他的如工作城市、月薪范围的检索,我们保持不变

        代码如下:

def url_get(data,i):#定义URL拼接

    url_1 = 'https://search.51job.com/list/000000,000000,0000,00,9,99,'

    url_2 = ',2,'

    url_yema = str(i)

    url_3 = '.html?lang=c&postchannel=0000&workyear=99&cotype=99&degreefrom=99&jobterm=99&companysize=99&' \

            'ord_field=0&dibiaoid=0&line=&welfare='

    url = url_1 +data+url_2+url_yema+url_3

return (url)

4.1.2 定义data、以及分析数据所需要的列表、变量

        代码如下:

data = str(input("请选择爬取职位或者公司: "))

xinzi_1 = []# 薪资列表 数据1

xinzi_2 = []# 薪资列表 数据2

xinzi_3 = []# 薪资列表 元的单位 返回10000 or 1000

xinzi_4 = []# 薪资列表 年or月单位

citf_l = []# 城市列表

exp_l = []  # 经验要求

edu_l = []  # 学历要求

count_people = 0 # 统计总爬取有效数据个数

count_xinzi = 0 # 统计总爬取薪资有效数据

xinzi_count1 = float(0) # 将如0.6-1万/月薪资的0.6转为float型,便于计算

xinzi_count2 = float(0) # 将如0.6-1万/月薪资的1转为float型,便于计算

citf_d = {}  # 字典

exp_d = {}  # 经验要求

edu_d = {}  # 学历要求

work_href = [] # 工作详细网址列表,便于二次循环爬取

f_file = data+"/"+"招聘_"+data + ".csv" # 定义根据输入的data自定义文件名并打开的变量

 

4.1.3 创建py相对路劲下的data文件夹

           先判断是否又此文件夹,没有则创建,此处path用的绝对路径。

           代码如下:

path = "D:/学习/东软/大三上期/脚本语言开发(陈汉斌)/yunxingDaiMa/招聘/"+data

if not os.path.exists(path):

os.mkdir(path)

4.1.4 打开csv文件,并写入表头

        此处ANSI为css的exeal编码,utf-8为txt编码。css编码不懂得可参考一下网址: https://www.runoob.com/python/python-func-open.htmlhttps://www.runoob.com/python/python-func-open.html https://www.runoob.com/python/python-func-open.html

        代码如下:

f = open(f_file, mode='w+', encoding='ANSI',

         newline='') 
csv_writer = csv.DictWriter(f, ['公司名称', '职位名称', '城市地区', '经验要求', '学历要求', '招聘人数','职位福利', '职位薪资', '职位发布日期', '职位详情网页'], dialect='excel')

csv_writer.writeheader()  # 写入表头

4.1.5 根据输入数据的data创建数据库的表名

   数据库的表名必须为全英文,不能为中文,所以需要定义is_Chinese函数,判断输入的data是否为中文,是中文根据输入的中文转换为拼音,不是则数据库名为'job_zhiwei_' + data。如输入:大数据,返回job_zhiwei_ dsj;输入prthon,则返回job_zhiwei_python,如果c//或者带有/*|\等符号的会报错,且网址也检索不出来。但是C++是网址有效检索数据,作为数据库表名则不行,有兴趣的可以自己完善下此代码,可将C++转换为C__,这中有效数据。

        输入阿里巴巴,输出数据库名效果如图:

     

 

 

 

 此函数参考网址Python将中文转成拼音_Kobe123brant的博客-CSDN博客

        代码如下:

def is_Chinese(word):

    for ch in word:

        if '\u4e00' <= ch <= '\u9fff':

            return True

    return False

if is_Chinese(data) :

    s = Pinyin().get_pinyin(data).split('-')

result = ''.join([i[0]. upper() for i in s])

    a = 'job_zhiwei_'+ result# 实现中文转义

else:

    a = 'job_zhiwei_' + data

  

4.1.6 链接数据库,写入数据库表头

        代码根据输入的data,创建不同的数据库表名;其中数据库的host为本地数据库,一般为127.0.0.1,也可为localhost;port为端口;databa为数据库;charset='utf8'为设置字符编码为utf8。

        创建后表头效果如图:

        代码如下:

#  连接数据库

conn = pymysql.connect(host="localhost", port=3306,user="root",password="",database="new_wen",charset='utf8')

cursor = conn.cursor() #定义数据库游标

#创建表job_zhiwei_'data'[ 'id', '公司名称', '职位名称', '城市地区', '经验要求', '学历要求', '招聘人数','职位福利', '职位薪资', '职位发布日期', '职位详情网页']

sql_create = """create table %s (

        id int(4) NOT NULL AUTO_INCREMENT ,

        ompany_name varchar(100) not null,

        job_name varchar(100) not null,

        job_area varchar(50) not null,

        job_exp varchar(20) not null,

        job_edu varchar(20) not null,

        recruiting_numbers varchar(20) not null,

        job_weal varchar(200)  null,

        job_pay varchar(50)  null,

        job_release_date varchar(20) not null,

        job_webpage varchar(500) not null,

        PRIMARY KEY (id)

        )""" %(a)

cursor.execute(sql_create) # 执行表创建函数

4.1.7 爬取数据并解析

      

       获取的原始数据reponse.test,是响应文本的文本数据

         reponse.test效果如图

        用re直接解析获取的reponse.test,命名为html_data,解析后是我们爬取到需要的招聘数据,为长字符串

        效果如图:

        在将获取到的字符串数据转换为json字典数据,并且解析json数据,写成键值对方式。每一个公司的数据为一个index,循环取出。pprint是测试是格式化输出的函数,输出后是标准的html网页代码格式

        json_data效果如图:

       

  index是for遍历解析的json数据

  获取的 index效果如图:

         最后在解析index,写入字典dit中,可写入csv和数据库中,并且将有效的职位数据写入存储分析薪资、地区、学历、经验多个列表。以便后面进行进一步的数据分析,最终获取到有效数据。

        dit效果如图:

        参考代码如下: 

 1 for i in range(1, 21): # range(1, 31)为循环1-30页
 2     url = url_get(data, i) # 调用url_get函数拼接url
 3     # 一个cookie用8页
 4     if i % 8 == 1:
 5         cookie_i1 += 1
 6         print("cookie={}".format(cookie_i1))
 7     if cookie_i1 == 2:
 8         break
 9     else:
10         headers = {
11             'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.20 Safari/537.36',
12             'Accept-Encoding': 'gzip, deflate, br',
13             'Cookie':cookie_j1[cookie_i1]
14             }
15         time.sleep(5)
16         response = session.get(url=url, headers=headers)  # 模拟get请求 返回信息response对象
17         print("********************正在爬取第{}页********************".format(i))
18         # 动态网页 response.json()获取json字典数据
19         # 保存下载图片 视屏 音频 获取响应体二进制数据 response.content()
20         #print(response.text) # 获取数据 获取响应文本的文本数据 reponse.test
21         html_date = re.findall('window.__SEARCH_RESULT__ = (.*?)</script>',response.text)[0]
22         #print(html_date)
23         #   把字符串数据转换为json字典数据
24         json_date = json.loads(html_date)
25         #格式化输出(好看)
26         #   pprint.pprint(json_date)
27         #解析json数据,写成键值对方式
28         search_esult = json_date['engine_jds']
29         #for遍历 提取列表中元素
30         for index in search_esult:
31             #pprint.pprint(index)
32             company_name = index["company_name"]  # 公司名称
33             title = index["job_name"] # 职位名称
34             info_list = index["attribute_text"] #职位要求基本信息如['成都', '3-4年经验', '本科', '招1人']
35             if len(info_list) == 4: # 将薪资基本信息完全的才输出
36                 citf = info_list[0]  # 城市
37                 exp = info_list[1]  # 经验要求
38                 edu = info_list[2]  # 学历要求
39                 people = info_list[3]  # 招聘人数
40                 I = info_list[0][0:2]  # 大地区获取
41                 citf_l = citf_l + [I]
42                 exp_l = exp_l + [exp]
43                 edu_l = edu_l + [edu]
44                 #列表转为字符串 空格分割
45                 #str(attribute_text)
46                 count_people= count_people+1 # 统计有效爬取人数
47                 #job_info = '|'.join(info_list) # 可以将列表转换为字符串,以|符号分割
48                 jobwelf = index["jobwelf"]  # 职位福利
49                 money = index["providesalary_text"]  # 职位薪资 4-4.5千/月 1.5-2.8万/月 15-20万/年
50                 updatedate = index["updatedate"]  # 职位发布日期
51                 job_href = index["job_href"]  # 职位详情网页
52                 work_href = work_href + [job_href]
53                 # 创建信息字典 键只能是元组、数字、字符串
54                 dit = {
55                     '公司名称': company_name,  '职位名称': title,
56                     '城市地区': citf,          '经验要求': exp,
57                     '学历要求': edu,           '招聘人数': people,
58                     '职位福利': jobwelf,       '职位薪资': money,
59                     '职位发布日期': updatedate, '职位详情网页': job_href, }
60                 csv_writer.writerow(dit)
61                 sql_insert = "insert into %s (ompany_name,job_name, job_area,job_exp,job_edu, " \
62                              "recruiting_numbers,job_weal,job_pay,job_release_date,job_webpage) " \
63                              "values('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s')" % (a,
64                             company_name, title, citf, exp, edu, people, jobwelf, money, updatedate, job_href)
65                 cursor.execute(sql_insert)
66                 conn.commit()  # 提交请求,不然不会插入数据
67                 print(dit)

 

4.2 数据存储

       数据存储为csv格式和mysql中。 

        data为C语言 csv存储效果如下: 

   

         

  data为阿里巴巴 数据库存储效果如下:

 

        参考代码如下:

1 csv_writer.writerow(dit) #将字典的数据写入到csv中
2 
3             sql_insert = "insert into %s (ompany_name,job_name, job_area,job_exp,job_edu, recruiting_numbers,job_weal,job_pay,job_release_date,job_webpage) values('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s')" % (a, company_name, title, citf, exp, edu, people, jobwelf, money, updatedate, job_href)
4 
5 cursor.execute(sql_insert)

 

4.3 数据分析

4.3.1 薪资分析

(1)薪资字符串切分并转换为不同的4个列表

        在薪资分析时有多个干扰字符串,如1.5千以下/月、100万以上/年这种薪资不便于计算,空的的薪资、时薪、日薪的不在参考范围,这类数据需要排除;此代码在有薪资全部基本信息的循环下。

      根据切分后输出的四个列表效果如图:

      参考代码如下:

 1 if money == '' or money[money.find("/") - 2:-3:1] == "" or [money[-1:]] == [""] or [money[-1:]] == [""]:
 2 
 3                 # 排除干扰项 1.5千以下/月、100万以上/年
 4 
 5                 pass
 6 
 7             else:
 8 
 9                 count_xinzi += 1
10 
11                 a1 = money.find("-")
12 
13                 a2 = money.find("/")
14 
15                 xinzi_1 = xinzi_1 + [money[0:a1]]  # 钱数字1
16 
17                 xinzi_2 = xinzi_2 + [money[a1 + 1:-3]]  # 钱数字2
18 
19                 if [money[a2 - 1:-1]] == ["万/"]:  # 输出单位万/ or 千/的数列代码
20 
21                     d1 = float(10000)
22 
23                 else:
24 
25                     d1 = float(1000)
26 
27                 if [money[-1:]] == [""]:  # 输出单位年的数列代码
28 
29                     d2 = float(1)
30 
31                 elif [money[-1:]] == [""]:
32 
33                     d2 = float(12)
34 
35                 xinzi_3 = xinzi_3 + [d1]  # 输出单位万/&千/ 的值10000 or 1000
36 
37                 xinzi_4 = xinzi_4 + [d2]  # 输出单位年的值1or12

(2)平均薪资分析

       根据薪资所切分的字符串转换的4个列表,以及count_xinzi(有效薪资数据个数)计算平均薪资的两个区间。

       最后计算的平均薪资效果如图:

       参考代码如下:

# 平均薪资分析
xinzi_5 = [] # 此处预定义一个空列表,将薪资分析的数据写入到csv文件中,以便进一步分析
xinzi_6 = [] #
num_list1 = [float(i) for i in xinzi_1]#将薪资数据的队列string型转为float型
num_list2 = [float(i) for i in xinzi_2]
for i in range(count_xinzi):
    j1 = num_list1[i]*xinzi_3[i]/xinzi_4[i]
    j2 = num_list2[i]*xinzi_3[i]/xinzi_4[i]
    xinzi_5+=[round(j1/1000, 1)] # 将薪资转换为K单位的薪资,如6.2K,输出6.2,并保留1位小数
    xinzi_6+=[round(j2/1000, 1)]
    xinzi_count1 = xinzi_count1+j1 
    xinzi_count2 = xinzi_count2+j2
average_wage1 = xinzi_count1/count_xinzi
average_wage2 = xinzi_count2/count_xinzi
f_fxinzi = data + "/" + data + "_" + "薪资" + "分析表.csv"
f = open(f_fxinzi, mode='w+', encoding='ANSI',newline='')  
csv_writer = csv.DictWriter(f, ['公司', '薪资数据1','薪资数据2','中位薪资'], dialect='excel')
csv_writer.writeheader()  # 写入表头
for i in range(count_xinzi):
    xinzi_zw = round((xinzi_5[i]+xinzi_6[i])/2, 1)
    dit3 = {
        '公司': work_gs[i],
        '薪资数据1': xinzi_5[i],
        '薪资数据2': xinzi_6[i],
        '中位薪资': xinzi_zw,
    }
    csv_writer.writerow(dit3)
# 输出平均薪资的计算结果
print("本次爬取有效职位共{}个,爬取有效薪资的数据为{}个,该职位或该公司的平均薪资为{}-{}元/月".
      format(count_people, count_xinzi, round(average_wage1, 0), round(average_wage2, 0)))

4.3.2 招聘地区、经验要求、学历要求分析

(1)创建字典分析函数:

       此函数有5个参数; l,d,k,v,z分别为列表、字典、csv写入第一列表头参数k,第二列表头参数v,以及创建csv的表名变量参数z。此函数是先打开文件,在写入表头。之后将之前预定义有数据的列表按照列表的数据统计为字典,最后将字典按照降序的方式遍历取值存储到csv中。定义好函数后,调用执行dict_analyse函数,将分析的数据写入scv中。

方法是

(2)执行dict_analyse函数

       列表统计转换字典后效果如图:

  经验要求图;

   学历要求图:

  地区划分图:

 

       函数定义参考代码如下:

 1 def dict_analyse(l,d,k,v,z):# 创建字典分析方法
 2 
 3     f_dqfb_file = data+"/"+"招聘_" + data + "_" + z + "分析.csv"
 4 
 5     f = open(f_dqfb_file, mode='w+', encoding='ANSI',
 6 
 7              newline='')  # ANSI为exeal编码 utf-8为txt编码 文件编码参考网址:https://www.runoob.com/python/python-func-open.html
 8 
 9     csv_writer = csv.DictWriter(f, [k, v], dialect='excel')
10 
11     csv_writer.writeheader()  # 写入表头
12 
13     for i in l:#分析区域分布,结果为字典
14 
15         d[i] = d.get(i,0)+1
16 
17     #print(d)
18 
19     for i,j in sorted(d.items(), key=lambda x:x[1], reverse=True):#value值降序排序并写入csv中
20 
21         dit2 = {
22 
23             k: i,
24 
25             v: j
26 
27         }
28 
29         csv_writer.writerow(dit2) #写入数据到csv中

4.4 根据数据分析保存的csv输出柱形图、扇形图

        输入"数据爬取"关键字效果如图:

输出文件效果图:

薪资扇形效果图:

 

 

 

地区、学历、经验扇形效果图:

地区、学历、经验柱形效果图:

 

 

 

        此子项目参考完整代码如下:

import pandas as pd
import matplotlib.pyplot as plt
#from 前程无忧_单网页爬取 import data
## 根据数据得到柱形图、扇形图
plt.rcParams['font.sans-serif']=['SimHei'] #显示中文标签
plt.rcParams['axes.unicode_minus'] = False
def ShowWorkArea (data,i,k,x_axle,y_axle):
    f = data+'/'+data+'_'+k+'分析表.csv'
    work = pd.read_csv(f, encoding='gbk', nrows=i)  # i为显示前几列
    # print(work.values)
    list1 = []
    list2 = []
    for o in work.values:
        list1 += [o[0]]
        list2 += [o[1]]
    plt.pie(x=list2,  labels=list1,  autopct='%1.1f%%'  ) # 绘图数据,添加标签,设置百分比的格式,这里保留一位小数
    plt.title(data+'_'+k+"分析扇形图")
    plt.savefig("D:/学习/东软/大三上期/脚本语言开发(陈汉斌)/yunxingDaiMa/招聘/" + data + '/'+data+'_'+k+"分析扇形图.png")  # 保存图片 #绝对路径
    # 显示图形
    plt.show()
    # x轴是招聘地区,y轴是招聘数量,让直方图排序显示,默认升序
    work.sort_values(by=y_axle,inplace=True,ascending = False)
    # 将直方图颜色统一设置为红色
    work.plot.bar(x=x_axle, y=y_axle, color='red')
    # 旋转X轴标签,让其横向写
    plt.xticks(rotation=360)
    j = str(i)
    plt.title(data+'_'+k+"分析柱形图")
    plt.savefig("D:/学习/东软/大三上期/脚本语言开发(陈汉斌)/yunxingDaiMa/招聘/"+data+'/'+data+'_'+k+"分析柱形图.png") #保存图片的绝对路径,读者根据自己的存储位置改
    plt.show()
def xinzi_analyze(data,k) :
    f = data+'/'+data+'_'+k+'分析表.csv'
    work = pd.read_csv(f, encoding='gbk')
    list = []
    for o in work.values:
        list += [o[3]]  #35-5/10=3
    d = (max(list)-min(list))/10           #分10组计算组距整除
    ls = [0,0,0,0,0,0,0,0,0,0]             #初始化列表ls,记录每组频数  L2标签为11组数据,每相邻两个组成一个标签,组成10个标签
    ls2=[min(list),min(list)+d*1,min(list)+d*2,min(list)+d*3,min(list)+d*4,min(list)+d*5,min(list)+d*6,min(list)+d*7,min(list)+d*8,min(list)+d*9,min(list)+d*10]
    # 创建标签ls3:
    ls3=[]
    for i in range(10):
        ch1 = [(str(round(ls2[i], 1))) + "k-" + (str(round(ls2[i + 1], 1)) + "k")]
        ls3 = ls3 + ch1
    for i in range(len(list)):      #在a中依次找出每组数据,并在ls中计数
        if list[i]   <= min(list)  + d * 1:
            ls[0] = ls[0] + 1
        elif list[i] <= min(list) + d * 2:
            ls[1] = ls[1] + 1
        elif list[i] <= min(list) + d * 3:
            ls[2] = ls[2] + 1
        elif list[i] <= min(list) + d * 4:
            ls[3] = ls[3] + 1
        elif list[i] <= min(list) + d * 5:
            ls[4] = ls[4] + 1
        elif list[i] <= min(list) + d * 6:
            ls[5] = ls[5] + 1
        elif list[i] <= min(list) + d * 7:
            ls[6] = ls[6] + 1
        elif list[i] <= min(list) + d * 8:
            ls[7] = ls[7] + 1
        elif list[i] <= min(list) + d * 9:
            ls[8] = ls[8] + 1
        elif list[i] <= min(list) + d * 10:
            ls[9] = ls[9] + 1
    plt.pie(x=ls, labels=ls3,  autopct='%1.1f%%'  )
    plt.axis("equal")#使之呈现“正圆”,默认扁圆
    plt.title(data+'_薪资分布扇形图')
    plt.savefig("D:/学习/东软/大三上期/脚本语言开发(陈汉斌)/yunxingDaiMa/招聘/" + data + '/' + data + "_薪资分析扇形图.png")  # 保存图片,绝对路径
    plt.show()
data = str(input("请输入查询的关键词:"))
#data = '人工智能'
#i = int(input("请输入查询的数量:"))
ShowWorkArea(data, 10, k="地区",x_axle="招聘地区",y_axle="招聘数量")  # 展示招聘职位地区分布
ShowWorkArea(data, 10, k="经验",x_axle="经验要求",y_axle="数量")  # 展示招聘职位地区分布
ShowWorkArea(data, 10, k="学历",x_axle="学历要求",y_axle="数量")  # 展示招聘职位地区分布
xinzi_analyze(data,k="薪资")
print("职位数据分析_画图运行成功!")

4.5 将输出在同一文件价的csv文件合并为同一个exeal

           输入‘’工程管理‘’合并csv文件效果如图:

           此子项目完整代码如下:

 1 import os
 2 
 3 import xlwt
 4 
 5 import csv
 6 
 7 def write_execl(csvfile, xlsfile, workbook, sheetname):
 8 
 9     # 创建表名,添加一个workbook的对象
10 
11     sheet = workbook.add_sheet(sheetname)
12 
13     # 读取csv文件内容,写入表 目录皆为下一目录
14 
15     reader = csv.reader(open('./'+data+'/'+csvfile, 'r'))
16 
17     i = 0
18 
19     for content in reader:
20 
21         for j in range(len(content)):
22 
23             sheet.write(i, j, content[j])
24 
25             j += 1
26 
27         i += 1
28 
29 # 目标execl文件名
30 
31 data = str(input("请输入合并的关键词:"))
32 
33 xlsfile = './'+data+'.xls'
34 
35 # 初始化workbook对象
36 
37 workbook = xlwt.Workbook()
38 
39 # 创建当前目录data目录下文件列表
40 
41 filelist = sorted(os.listdir('./'+data+'/'))
42 
43 #print(filelist)
44 
45 for file in filelist:
46 
47     # 匹配以csv结尾的文件
48 
49     if file.endswith('.csv'):
50 
51         # 匹配出表名
52 
53         sheetname = file.replace('.csv', '')
54 
55         # 使用函数将csv文件内容导入到execl
56 
57         write_execl(file, xlsfile, workbook, sheetname)
58 
59 workbook.save('./'+data+'/'+xlsfile)

 

4.6 根据爬取到的网址再次爬取岗位要求、岗位职责等信息

        根据之前爬取到的职位网址再次模拟网址请求,进入职位详情页面获取岗位要求、岗位职责等信息。

此功能注:此项功能由于网站有反扒机制,代码尚未完善。需要手动添加cookie,但是一次能爬取6-15个网站。后面会完善。

        输入‘’工程管理‘’爬取岗位要求、岗位职责效果如图:

        此子项目完整参考代码如下:

import requests# 模拟请求 post get
import time
import parsel # 数据解析模块  包含css xpath
import pandas as pd # 数据类型和分析工具库
session = requests.session()# 为了保持代码中所有的session统一
data = str(input("请输入爬取的关键词:"))
f = open(data+"/"+"招聘_"+data + ".txt", "w+", encoding="utf-8")
f2 = data+'/招聘_'+data+'.csv'
work = pd.read_csv(f2, encoding='gbk')
work_href = []
for o in work.values:
    work_href += [o[9]]#网页列表创建
print("有效网页有{}个".format(len(work_href)))
count_i= 1
cookie_i = -1
# 此处cookie需要手动添加
cookie_j2 = [
        '_uab_collina=164040561244084158170825; guid=6d76337f83a21caacfd07e454cd82029; nsearch=jobarea%3D%26%7C%26ord_field%3D%26%7C%26recentSearch0%3D%26%7C%26recentSearch1%3D%26%7C%26recentSearch2%3D%26%7C%26recentSearch3%3D%26%7C%26recentSearch4%3D%26%7C%26collapse_expansion%3D; search=jobarea%7E%60090200%7C%21ord_field%7E%600%7C%21recentSearch0%7E%60090200%A1%FB%A1%FA000000%A1%FB%A1%FA0000%A1%FB%A1%FA00%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA9%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA0%A1%FB%A1%FA%A1%FB%A1%FA2%A1%FB%A1%FA1%7C%21; acw_tc=76b20fec16404056112165750e4a3e0c69e32b95740f4dab8a0269f0369c0f; acw_sc__v2=61c69a6b55ed94e57ed07c823ebd93024a27e544; ssxmod_itna=eqAxRDBQit0=u0Dl+QmqG=eDQCi=7rkhbK=HDl=BoxA5D8D6DQeGTb2eYkpkKzkinDPiDuC2TrQAiAraRp=Q7DcIfHmDB3DEx06+T+YxiicDCeDIDWeDiDG4GmS4GtDpxG=Dj0FUZMUxi3Dbh=Df4DmDGY9QqDgDYQDGMp6D7QDIw=Q38q9bCLKLLRg33rY7qDMUeGXl7ctwmaHy7XedP+7QDqDC2G=91G=/a3QQiiWQqGybKGuULt/SfR1sLNleje4i2D4mGvem0qa38DeFGqpSU+xDLx=eUmsFGxEiYQX28qDG+kldbD==; ssxmod_itna2=eqAxRDBQit0=u0Dl+QmqG=eDQCi=7rkhbK=D61FD405eR403ORL7jk2DuQLw5MoIh=jDnRG1uFlqoqwYuaBgjOYQ8G8ILOXaew0O=Q3wi7wpg=iCrj=M+jZ8B4ZP196C65ldZ=mZOhvGWdiGQMLKQqhO3TLRfxPDKwYDFqD2Y8q190qHG0wKeD==; _ga=GA1.3.2041326383.1640405619; _gid=GA1.3.1948191126.1640405619; _gat=1',
        'guid=b61b9790083897515ead52b430fa7f7c; _ga=GA1.3.732902233.1639826279; acw_tc=2f624a3e16402705890986233e15eafe05670d10f2064fbb56641531540303; acw_sc__v2=61c48afdb72c254f7a8458401de17d24862a0d40; ssxmod_itna=Qq0xciiQKCqYu0xl4iTbID9ix0B7COCdeWbqIoDl6YxA5D8D6DQeGTbRWeCbtzKBiGhfGq077iKae90fhxaQDE4itWWc2veDHxY=DUPxueDxOq0rD74irDDxD3Db4QDSDWKD9Gqi3DEBKDaxDbDimkAxGCDeKD0xwHDQKDugFKq0hkPSa+yPO1qW7ajxDzUxG1T40HqA8I=U8LCBv3Ax0k940Og1vknPoDUBqFt7bNtiGeraQ3A0ialYxqorrKimGotmroTO6x7DzNCDDWqCrNqYD===; ssxmod_itna2=Qq0xciiQKCqYu0xl4iTbID9ix0B7COCdeWbqWD6p4mqrF9DDsKjjDL01M4NLvCdx5OSCeQq2GxOYqAT3qi4lyjE5kIdYxOKV2jki3==m=29eQUrg3mkErdk0GGKcYuR=5L=svjqR0=GsD3Pto7BOc6vxRlITY=vhQxnkYEukQZTKdpW4uOyNMpO7CfuIFzuI4hcvkanrED07qx08DY9iC7qetnnDoihDD===',
        'guid=b61b9790083897515ead52b430fa7f7c; _ga=GA1.3.732902233.1639826279; acw_tc=2f624a3e16402705890986233e15eafe05670d10f2064fbb56641531540303; acw_sc__v2=61c48afdb72c254f7a8458401de17d24862a0d40; ssxmod_itna=eqGOGK4UrTD5GHvxCDjoxmrrjeyDitOiDcitD0yioeGzDAxn40iDtxosBiDprmEn5PEe47I3pQ8opqQL3EAW3KebPSife/GDB3DEx0=wAYxYYkDt4DTD34DYDixibhxi5GRD0FCDbxYpyDA3Di4D+zd=DmqG0DDt7/4G2D7Uyj0Y4zu0XWeNo6uYqqE=D0M=DjwbD/RAacnrF1pGVbo=DzMFDtTNlzLtox0PsR3wqGAvQ+73w=SDvaYezGi3v6Yqwi05dCBDKUUP3AA54DDf1iF4xD==; ssxmod_itna2=eqGOGK4UrTD5GHvxCDjoxmrrjeyDitOiDcmxnKS2OKDsp=DLBDQwQk9kIQidqRKlS9NOO3g+5hGYgaQmLkdXea9WAextirczlKGlGXXYuKnrbs8gSWLPH+dUP/BGXp8yPigC=NvBHC6vka=PHpWyCYSaiCEi+XaGNY3+dN9u=GEybZYIIqjvvAxSmvE5rNbP4/mfGhBuLWp2LZm38O0EveB+qFYwXPWqxOWqQ9p5iBRW8kOSHtmyHsPOiLgRbz/9bDuP9g6WIqC68RGnbllRW9h4Dw6dDLxG7M+iQiO005ebmO7hP4D=',
        'guid=b61b9790083897515ead52b430fa7f7c; _ga=GA1.3.732902233.1639826279; acw_tc=2f624a3e16402705890986233e15eafe05670d10f2064fbb56641531540303; acw_sc__v2=61c48afdb72c254f7a8458401de17d24862a0d40; ssxmod_itna=QqfO0IxUgGCYGQDXDnD+r8NWDQiPyh900eerKDsFADSxGKidDqxBmWQPDtCbizeBATrfGqR7Bi31kFrixhW3DpfxpW1lox0aDbqGkpRQxiicDCeDIDWeDiDG4Gm/4GtDpxG6yDm4i36xA3Di4D+8MQDmqG0DDUHS4G2D7U9bGw9Yjde6qbSKG0KFqDl8qDMmeGXKDcdOQcagAXWtqGyAPGu0uU9IqbDC2vLGG4oSx41mYfh5G4IaAxzmD3IND+xjG7Yti53If8W0DwzBDDAGil3eD===; ssxmod_itna2=QqfO0IxUgGCYGQDXDnD+r8NWDQiPyh900eexikApvDlrrxxj+PpQdrdvQiduWD0EchzFUxEp21FR2jY6qXI2qY=h3YnAyNGCbbBIcmqm6W2BRn8mCyb3oa3FMRC9Qy+l1wlQ8gltsmohF4C53FwXnnGiYK0K0j04tKAhuBhQdI24GixG2l4GcDiQXjAe4zwwYa10QaG4xD==',
        'guid=b61b9790083897515ead52b430fa7f7c; _ga=GA1.3.732902233.1639826279; acw_tc=2f624a3e16402705890986233e15eafe05670d10f2064fbb56641531540303; acw_sc__v2=61c48afdb72c254f7a8458401de17d24862a0d40; ssxmod_itna=QqAx9iDteDwpGCDzrD2YLYKiK0=jt++feoNQD/fDfr4iNDnD8x7YDvmma7QgFObnxcXx7F=0DfeYWrDbRtq7G44xW=Qox0aDbqGkq9GrQGGjxBYDQxAYDGDDPDogPD1D3qDkXxYPGW8qiaDGeDec9ODY5DhxDC00PDwx0C6OGW6rYHY85mn=DhijKDBcKD9ooDs=DfQnKwEU3qZhRODlF6DCKz9c9Ci4GdI7cKeYxNkWR3AiCxPnxeo0T5510KqWr2klDx1nhxknRPlQtDia2elmGDD=; ssxmod_itna2=QqAx9iDteDwpGCDzrD2YLYKiK0=jt++feoNG9tM9DBdOdx7ph3ABa9xg=I7d9=2S2kDG8D3QFpFqbFETtvK7r0O4mD8E+Rw1+h=BTFzcfCSRX=PHEBy0HLZckKGx28TlI68MrNU96Yhp384LgtficGMLD=BeDKwxFD7=DeTRvG+hez70eKGP5DpeoOBEe0nqYeD='

        ]
for i in work_href: # 一次coolie至多15次
    headers2 = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3880.400 QQBrowser/10.8.4554.400',
        'Accept-Encoding': 'gzip, deflate, br',
        'Cookie':cookie_j2[cookie_i]
    }

    if count_i % 8 == 1 :  # 输出为1,2,3,4,5,6,7,0为8次循环,一次cookie用8个网页
        cookie_i += 1
    if cookie_i == 1 :# 爬取5*count_i个岗位数据存入txt中
            break
    else:
        print("cookie_i={}".format(cookie_i))
        print('正在爬取第{}页,爬取网址:{}'.format(count_i,i)) # 循环网址
        count_i += 1
        time.sleep(5)
        response = session.get(url=i, headers=headers2)  # 模拟get请求 返回信息response对象
        html = response.text.encode('iso-8859-1').decode('gbk')
        # print(html)
        selector = parsel.Selector(html)
        str_list = selector.xpath(' //div[@class="bmsg job_msg inbox"]//p/text()').getall() # 获取职位信息标签获取
        str_info = '\n'.join(str_list)  # 列表 转换为字符串 \n划分
        print(str_info)
        print()
        f.write(str_info)
        f.write('\r\n')
print("工作职责写入成功")

5、完整代码

5.1 主网页爬取完整代码

  代码如下:

import requests# 模拟请求 post get
from xpinyin import Pinyin # 将中文输出为拼音
import pprint # 格式化输出模块
import os # 操作文件和目录
import re # 正则表达式模块 内置
import json
import csv # 输出csv的库
import pymysql # 数据库
import time # 计算机内部时间库
session = requests.session()# 为了保持代码中所有的session统一
def url_get(data,i):#定义URL拼接
    url_1 = 'https://search.51job.com/list/000000,000000,0000,00,9,99,'
    url_2 = ',2,'
    url_yema = str(i)
    url_3 = '.html?lang=c&postchannel=0000&workyear=99&cotype=99&degreefrom=99&' \
            'jobterm=99&companysize=99&ord_field=0&dibiaoid=0&line=&welfare='
    url = url_1 +data+url_2+url_yema+url_3
    return (url)
# 代码运行
data = str(input("请选择爬取职位或者公司: "))
xinzi_1 = []# 薪资列表 数据1
xinzi_2 = []# 薪资列表 数据2
xinzi_3 = []# 薪资列表 元的单位 返回10000 or 1000
xinzi_4 = []# 薪资列表 年or月单位
citf_l = []# 城市列表
exp_l = []  # 经验要求
edu_l = []  # 学历要求
count_people = 0 # 统计总爬取有效数据个数
count_xinzi = 0 # 统计总爬取薪资有效数据
xinzi_count1 = float(0) # 将如0.6-1万/月薪资的0.6转为float型,便于计算
xinzi_count2 = float(0) # 将如0.6-1万/月薪资的1转为float型,便于计算
citf_d = {}  # 字典
exp_d = {}  # 经验要求
edu_d = {}  # 学历要求
work_gs = []
work_href = [] # 工作详细网址列表,便于二次循环爬取
f_file = data+"/"+"招聘_"+data + ".csv" # 定义根据输入的data自定义文件名并打开的变量
# 创建data文件夹
path = "D:/学习/东软/大三上期/脚本语言开发(陈汉斌)/yunxingDaiMa/招聘/"+data
if not os.path.exists(path):
    os.mkdir(path)
f = open(f_file, mode='w+', encoding='ANSI',
         newline='')  # ANSI为css的exeal编码 utf-8为txt编码 https://www.runoob.com/python/python-func-open.html
csv_writer = csv.DictWriter(f, ['公司名称', '职位名称', '城市地区', '经验要求', '学历要求', '招聘人数','职位福利', '职位薪资', '职位发布日期', '职位详情网页'], dialect='excel')
csv_writer.writeheader()  # 写入表头

# 判断输入语句是否为中文,是中文变量a为'job_zhiwei_'+ result,不是a为'job_zhiwei_' + data,a是数据库名
# 参考网址: https://blog.csdn.net/Kobe123brant/article/details/110326353?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163990869516780357286336%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=163990869516780357286336&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-2-110326353.pc_search_result_cache&utm_term=python%E5%B0%86%E4%B8%AD%E6%96%87%E8%BD%AC%E6%8D%A2%E4%B8%BA%E6%8B%BC%E9%9F%B3%E7%9A%84%E6%96%B9%E6%B3%95&spm=1018.2226.3001.4187
# 数据库名预定义函数,不需要数据库可删除以下代码
def is_Chinese(word):
    for ch in word:
        if '\u4e00' <= ch <= '\u9fff':
            return True
    return False
if is_Chinese(data) :
    s = Pinyin().get_pinyin(data).split('-')
    result = ''.join([i[0]. upper() for i in s]) # 中文转换为首字母 如大数据:DSJ
    a = 'job_zhiwei_'+ result# 实现中文转义
else:
    a = 'job_zhiwei_' + data
# print("******************************测试分割以下为数据库变量名字a************************************")
# print(a)
#  连接数据库
conn = pymysql.connect(host="localhost", port=3306,user="root",password="",database="new_wen",charset='utf8')
cursor = conn.cursor()# 定义数据库游标
#创建表job_zhiwei_'data'[ 'id', '公司名称', '职位名称', '城市地区', '经验要求', '学历要求', '招聘人数','职位福利', '职位薪资', '职位发布日期', '职位详情网页']
sql_create = """create table %s (
        id int(4) NOT NULL AUTO_INCREMENT ,
        ompany_name varchar(100) not null,
        job_name varchar(100) not null,
        job_area varchar(50) not null,
        job_exp varchar(20) not null,
        job_edu varchar(20) not null,
        recruiting_numbers varchar(20) not null,
        job_weal varchar(200)  null,
        job_pay varchar(50)  null,
        job_release_date varchar(20) not null,
        job_webpage varchar(500) not null,
        PRIMARY KEY (id)
        )""" %(a)
cursor.execute(sql_create) # 执行创建数据库
cookie_i1 = -1
# 此处cookie需要手动添加5个
cookie_j1 = [
        '_uab_collina=164009531079133854257018; guid=b61b9790083897515ead52b430fa7f7c; nsearch=jobarea%3D%26%7C%26ord_field%3D%26%7C%26recentSearch0%3D%26%7C%26recentSearch1%3D%26%7C%26recentSearch2%3D%26%7C%26recentSearch3%3D%26%7C%26recentSearch4%3D%26%7C%26collapse_expansion%3D; search=jobarea%7E%60000000%7C%21ord_field%7E%600%7C%21recentSearch0%7E%60000000%A1%FB%A1%FA000000%A1%FB%A1%FA0000%A1%FB%A1%FA00%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA9%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA0%A1%FB%A1%FA%A1%FB%A1%FA2%A1%FB%A1%FA1%7C%21recentSearch1%7E%60000000%A1%FB%A1%FA000000%A1%FB%A1%FA0000%A1%FB%A1%FA00%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA9%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA0%A1%FB%A1%FA%CA%FD%BE%DD%BF%AA%B7%A2%A1%FB%A1%FA2%A1%FB%A1%FA1%7C%21recentSearch2%7E%60000000%A1%FB%A1%FA000000%A1%FB%A1%FA0000%A1%FB%A1%FA00%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA9%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA0%A1%FB%A1%FAcss%A1%FB%A1%FA2%A1%FB%A1%FA1%7C%21recentSearch3%7E%60000000%A1%FB%A1%FA000000%A1%FB%A1%FA0000%A1%FB%A1%FA00%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA9%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA0%A1%FB%A1%FA%B4%F3%CA%FD%BE%DD%A1%FB%A1%FA2%A1%FB%A1%FA1%7C%21; acw_tc=76b20fed16401872784651156e73596d44930468e6d412e280ea9ea5b4f281; acw_sc__v2=61c3458e4cf4f427e44da3d4d2b1abe8417b4db4; ssxmod_itna=eqUx9DgD0DuDn7DRGDzgKnh2EKDCY+lWWCCRSRDBkDAK3DZDiqAPGhDC++9Om3brmF3DE8YwQ677ipv=j8rApfqYWh0h3tVADB3DEx0=KrRWKiiBDCeDIDWeDiDG4Gm4qGtDpxG=gDm4GWGqGfDDoDY4tcDitD4qDBmgdDKqGgGuDKWDUqV82lIltKtexyDDNBD0U3xBdK71u5kZaPDWPcDB=CxBjZRqtMIeDH/oLYtrhslG+Et/h5YDxsmSxo77GT+0DNCGGqe3q3bzCDGb82EGxxD=; ssxmod_itna2=eqUx9DgD0DuDn7DRGDzgKnh2EKDCY+lWWCCRSD8dpgxGX=G8DFgwOUc2aOIyoRPGF+nkKxK45WCDeNMI=evUG3qS7Kvmi=G=I9GeIPuGi+xE20oaAhVllC=4X5CLckNu+iI5azQWlcaU25HrBPseE2kc65WyQGHyePTU7Ib3bu8UogpmP9mR2pImhvIYB44tFwtC2w+Q6nEegfHqQk=mUmCnBfChgfTHcLdl+d2dr9=nS+02agbtpA2bMInrAuptLmLY6ZfUCT+zrnwR1q=3zwGIdI2HcIjgaTm7awT36/upVQSmrT7rDoeEsUioo4iehdiS7qYa20oURYNhYRh5o4YlD1ie5KuN1Wz9+QL2N2DowWQ5fYNloFQKzE7Kfbl0+v3=joNwL34bFIricf3N4Yr0QATAD1zRe3AkClOsPD3gTqffDPWbo+Q98ftoawRPs3rRg38SpigbxLjcYzUb5+aoXGNHbtFb3PjYtiUidPD7QDxGcDG7Dfxz0DywDYiDD===',
        '_uab_collina=164009531079133854257018; guid=b61b9790083897515ead52b430fa7f7c; nsearch=jobarea%3D%26%7C%26ord_field%3D%26%7C%26recentSearch0%3D%26%7C%26recentSearch1%3D%26%7C%26recentSearch2%3D%26%7C%26recentSearch3%3D%26%7C%26recentSearch4%3D%26%7C%26collapse_expansion%3D; search=jobarea%7E%60000000%7C%21ord_field%7E%600%7C%21recentSearch0%7E%60000000%A1%FB%A1%FA000000%A1%FB%A1%FA0000%A1%FB%A1%FA00%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA9%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA0%A1%FB%A1%FA%A1%FB%A1%FA2%A1%FB%A1%FA1%7C%21recentSearch1%7E%60000000%A1%FB%A1%FA000000%A1%FB%A1%FA0000%A1%FB%A1%FA00%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA9%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA0%A1%FB%A1%FA%CA%FD%BE%DD%BF%AA%B7%A2%A1%FB%A1%FA2%A1%FB%A1%FA1%7C%21recentSearch2%7E%60000000%A1%FB%A1%FA000000%A1%FB%A1%FA0000%A1%FB%A1%FA00%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA9%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA0%A1%FB%A1%FAcss%A1%FB%A1%FA2%A1%FB%A1%FA1%7C%21recentSearch3%7E%60000000%A1%FB%A1%FA000000%A1%FB%A1%FA0000%A1%FB%A1%FA00%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA9%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA0%A1%FB%A1%FA%B4%F3%CA%FD%BE%DD%A1%FB%A1%FA2%A1%FB%A1%FA1%7C%21; acw_tc=76b20fed16401872784651156e73596d44930468e6d412e280ea9ea5b4f281; acw_sc__v2=61c3458e4cf4f427e44da3d4d2b1abe8417b4db4; ssxmod_itna=QuG=BKGKD5emxDq0LeYKO6mGcc2Dxmqmwn4KDsaDcYxA5D8D6DQeGTbRQTrtLiziZkDIaKicYhfa5FhSihiA4ECwmbDU4i8DCkiE3pDem=D5xGoDPxDeDADYoUDAqiOD7L=DEDmR8DaxDbDin8pxGCDeKD0xwFDQKDu6FxqD284fphngACqY7YExDzLxG1i40HqCfp3+ffij53px0ku40O9ry82gYDUCpbtmGelC+T4Ni4osiYdQrToHGqqW20tW04oCDW/Gx2sqxDicReqYD===; ssxmod_itna2=QuG=BKGKD5emxDq0LeYKO6mGcc2Dxmqmwn4ikvqhqDlEaDjbpublfk6ZG==i=P8xApq2eFoI+FY5Qkr+hYrSYRoDwxEPGcDYFFtD1aOlxxD=',
        '',
        '',
        ''
        ]
for i in range(1, 21): # range(1, 31)为循环1-30页
    url = url_get(data, i) # 调用url_get函数拼接url
    # 一个cookie用8页
    if i % 8 == 1:
        cookie_i1 += 1
        print("cookie={}".format(cookie_i1))
    if cookie_i1 == 2:
        break
    else:
        headers = {
            'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.20 Safari/537.36',
            'Accept-Encoding': 'gzip, deflate, br',
            'Cookie':cookie_j1[cookie_i1]
            }
        time.sleep(5)
        response = session.get(url=url, headers=headers)  # 模拟get请求 返回信息response对象
        print("********************正在爬取第{}页********************".format(i))
        # 动态网页 response.json()获取json字典数据
        # 保存下载图片 视屏 音频 获取响应体二进制数据 response.content()
        #print(response.text) # 获取数据 获取响应文本的文本数据 reponse.test
        html_date = re.findall('window.__SEARCH_RESULT__ = (.*?)</script>',response.text)[0]
        #print(html_date)
        #   把字符串数据转换为json字典数据
        json_date = json.loads(html_date)
        #格式化输出(好看)
        #   pprint.pprint(json_date)
        #解析json数据,写成键值对方式
        search_esult = json_date['engine_jds']
        #for遍历 提取列表中元素
        for index in search_esult:
            #pprint.pprint(index)
            company_name = index["company_name"]  # 公司名称
            title = index["job_name"] # 职位名称
            info_list = index["attribute_text"] #职位要求基本信息如['成都', '3-4年经验', '本科', '招1人']
            if len(info_list) == 4: # 将薪资基本信息完全的才输出
                citf = info_list[0]  # 城市
                exp = info_list[1]  # 经验要求
                edu = info_list[2]  # 学历要求
                people = info_list[3]  # 招聘人数
                I = info_list[0][0:2]  # 大地区获取
                citf_l = citf_l + [I]
                exp_l = exp_l + [exp]
                edu_l = edu_l + [edu]
                #列表转为字符串 空格分割
                #str(attribute_text)
                count_people= count_people+1 # 统计有效爬取人数
                #job_info = '|'.join(info_list) # 可以将列表转换为字符串,以|符号分割
                jobwelf = index["jobwelf"]  # 职位福利
                money = index["providesalary_text"]  # 职位薪资 4-4.5千/月 1.5-2.8万/月 15-20万/年
                updatedate = index["updatedate"]  # 职位发布日期
                job_href = index["job_href"]  # 职位详情网页
                work_href = work_href + [job_href]
                # 创建信息字典 键只能是元组、数字、字符串
                dit = {
                    '公司名称': company_name,  '职位名称': title,
                    '城市地区': citf,          '经验要求': exp,
                    '学历要求': edu,           '招聘人数': people,
                    '职位福利': jobwelf,       '职位薪资': money,
                    '职位发布日期': updatedate, '职位详情网页': job_href, }
                csv_writer.writerow(dit)
                sql_insert = "insert into %s (ompany_name,job_name, job_area,job_exp,job_edu, " \
                             "recruiting_numbers,job_weal,job_pay,job_release_date,job_webpage) " \
                             "values('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s')" % (a,
                            company_name, title, citf, exp, edu, people, jobwelf, money, updatedate, job_href)
                cursor.execute(sql_insert)
                conn.commit()  # 提交请求,不然不会插入数据
                print(dit)
                ### 薪资分析代码
                if money == '' or money[money.find("/") - 2:-3:1] == "" or [money[-1:]] == [""] or [money[-1:]] == [""]:
                    # 排除干扰项 1.5千以下/月、100万以上/年
                    pass
                else:
                    count_xinzi += 1
                    a1 = money.find("-")
                    a2 = money.find("/")
                    work_gs+=[company_name]
                    xinzi_1 = xinzi_1 + [money[0:a1]]  # 钱数字1
                    xinzi_2 = xinzi_2 + [money[a1 + 1:-3]]  # 钱数字2
                    if [money[a2 - 1:-1]] == ["万/"]:  # 输出单位万/ or 千/的数列代码
                        d1 = float(10000)
                    else:
                        d1 = float(1000)
                    if [money[-1:]] == [""]:  # 输出单位年的数列代码
                        d2 = float(1)
                    elif [money[-1:]] == [""]:
                        d2 = float(12)
                    xinzi_3 = xinzi_3 + [d1]  # 输出单位万/&千/ 的值10000 or 1000
                    xinzi_4 = xinzi_4 + [d2]  # 输出单位月和年的值1或者12
    #break # 调试单次循环,便于查看
# 招聘数据、分析写入 字典数据排序(内容,关键点=匿名函数以x中第二个元素为标准排序,采用逆序)[地区列表]
cursor.close()  # 关闭数据库链接
conn.close()
def dict_analyse(l,d,k,v,z):# 创建字典分析方法
    f_dqfb_file = data+"/"+data + "_" + z + "分析表.csv"
    f = open(f_dqfb_file, mode='w+', encoding='ANSI',
             newline='')  # ANSI为exeal编码 utf-8为txt编码 https://www.runoob.com/python/python-func-open.html
    csv_writer = csv.DictWriter(f, [k, v], dialect='excel')
    csv_writer.writeheader()  # 写入表头
    for i in l:#分析区域分布,结果为字典
        d[i] = d.get(i,0)+1
    #print(d)
    for i,j in sorted(d.items(), key=lambda x:x[1], reverse=True):# value值降序排序并写入csv中
        dit2 = {
            k: i,
            v: j
        }
        csv_writer.writerow(dit2)
dict_analyse(citf_l, citf_d, k="招聘地区", v="招聘数量",z="地区") # 调用执行dict_analyse函数,写入scv中
dict_analyse(exp_l, exp_d, k="经验要求", v="数量",z="经验")
dict_analyse(edu_l, edu_d, k="学历要求", v="数量",z="学历")
# 平均薪资分析
xinzi_5 = [] # 此处预定义一个空列表,将薪资分析的数据写入到csv文件中,以便进一步分析
xinzi_6 = [] #
num_list1 = [float(i) for i in xinzi_1]#将薪资数据的队列string型转为float型
num_list2 = [float(i) for i in xinzi_2]
for i in range(count_xinzi):
    j1 = num_list1[i]*xinzi_3[i]/xinzi_4[i]
    j2 = num_list2[i]*xinzi_3[i]/xinzi_4[i]
    xinzi_5+=[round(j1/1000, 1)] # 将薪资转换为K单位的薪资,如6.2K,输出6.2,并保留1位小数
    xinzi_6+=[round(j2/1000, 1)]
    xinzi_count1 = xinzi_count1+j1
    xinzi_count2 = xinzi_count2+j2
average_wage1 = xinzi_count1/count_xinzi
average_wage2 = xinzi_count2/count_xinzi
f_fxinzi = data + "/" + data + "_" + "薪资" + "分析表.csv"
f = open(f_fxinzi, mode='w+', encoding='ANSI',newline='')
csv_writer = csv.DictWriter(f, ['公司', '薪资数据1','薪资数据2','中位薪资'], dialect='excel')
csv_writer.writeheader()  # 写入表头
for i in range(count_xinzi):
    xinzi_zw = round((xinzi_5[i]+xinzi_6[i])/2, 1)
    dit3 = {
        '公司': work_gs[i],
        '薪资数据1': xinzi_5[i],
        '薪资数据2': xinzi_6[i],
        '中位薪资': xinzi_zw,
    }
    csv_writer.writerow(dit3)
# 输出平均薪资的计算结果
print("本次爬取有效职位共{}个,爬取有效薪资的数据为{}个,该职位或该公司的平均薪资为{}-{}元/月".
      format(count_people, count_xinzi, round(average_wage1, 0), round(average_wage2, 0)))

 

5.2 职位详情网页爬取完整代码

  代码如下:

import requests# 模拟请求 post get
import time
import parsel # 数据解析模块  包含css xpath
import pandas as pd # 数据类型和分析工具库
session = requests.session()# 为了保持代码中所有的session统一
data = str(input("请输入爬取的关键词:"))
f = open(data+"/"+"招聘_"+data + ".txt", "w+", encoding="utf-8")
f2 = data+'/招聘_'+data+'.csv'
work = pd.read_csv(f2, encoding='gbk')
work_href = []
for o in work.values:
    work_href += [o[9]]#网页列表创建
print("有效网页有{}个".format(len(work_href)))
count_i= 1
cookie_i = -1
# 此处cookie需要手动添加
cookie_j2 = [
        '_uab_collina=164040561244084158170825; guid=6d76337f83a21caacfd07e454cd82029; nsearch=jobarea%3D%26%7C%26ord_field%3D%26%7C%26recentSearch0%3D%26%7C%26recentSearch1%3D%26%7C%26recentSearch2%3D%26%7C%26recentSearch3%3D%26%7C%26recentSearch4%3D%26%7C%26collapse_expansion%3D; search=jobarea%7E%60090200%7C%21ord_field%7E%600%7C%21recentSearch0%7E%60090200%A1%FB%A1%FA000000%A1%FB%A1%FA0000%A1%FB%A1%FA00%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA9%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA0%A1%FB%A1%FA%A1%FB%A1%FA2%A1%FB%A1%FA1%7C%21; acw_tc=76b20fec16404056112165750e4a3e0c69e32b95740f4dab8a0269f0369c0f; acw_sc__v2=61c69a6b55ed94e57ed07c823ebd93024a27e544; ssxmod_itna=eqAxRDBQit0=u0Dl+QmqG=eDQCi=7rkhbK=HDl=BoxA5D8D6DQeGTb2eYkpkKzkinDPiDuC2TrQAiAraRp=Q7DcIfHmDB3DEx06+T+YxiicDCeDIDWeDiDG4GmS4GtDpxG=Dj0FUZMUxi3Dbh=Df4DmDGY9QqDgDYQDGMp6D7QDIw=Q38q9bCLKLLRg33rY7qDMUeGXl7ctwmaHy7XedP+7QDqDC2G=91G=/a3QQiiWQqGybKGuULt/SfR1sLNleje4i2D4mGvem0qa38DeFGqpSU+xDLx=eUmsFGxEiYQX28qDG+kldbD==; ssxmod_itna2=eqAxRDBQit0=u0Dl+QmqG=eDQCi=7rkhbK=D61FD405eR403ORL7jk2DuQLw5MoIh=jDnRG1uFlqoqwYuaBgjOYQ8G8ILOXaew0O=Q3wi7wpg=iCrj=M+jZ8B4ZP196C65ldZ=mZOhvGWdiGQMLKQqhO3TLRfxPDKwYDFqD2Y8q190qHG0wKeD==; _ga=GA1.3.2041326383.1640405619; _gid=GA1.3.1948191126.1640405619; _gat=1',
        'guid=b61b9790083897515ead52b430fa7f7c; _ga=GA1.3.732902233.1639826279; acw_tc=2f624a3e16402705890986233e15eafe05670d10f2064fbb56641531540303; acw_sc__v2=61c48afdb72c254f7a8458401de17d24862a0d40; ssxmod_itna=Qq0xciiQKCqYu0xl4iTbID9ix0B7COCdeWbqIoDl6YxA5D8D6DQeGTbRWeCbtzKBiGhfGq077iKae90fhxaQDE4itWWc2veDHxY=DUPxueDxOq0rD74irDDxD3Db4QDSDWKD9Gqi3DEBKDaxDbDimkAxGCDeKD0xwHDQKDugFKq0hkPSa+yPO1qW7ajxDzUxG1T40HqA8I=U8LCBv3Ax0k940Og1vknPoDUBqFt7bNtiGeraQ3A0ialYxqorrKimGotmroTO6x7DzNCDDWqCrNqYD===; ssxmod_itna2=Qq0xciiQKCqYu0xl4iTbID9ix0B7COCdeWbqWD6p4mqrF9DDsKjjDL01M4NLvCdx5OSCeQq2GxOYqAT3qi4lyjE5kIdYxOKV2jki3==m=29eQUrg3mkErdk0GGKcYuR=5L=svjqR0=GsD3Pto7BOc6vxRlITY=vhQxnkYEukQZTKdpW4uOyNMpO7CfuIFzuI4hcvkanrED07qx08DY9iC7qetnnDoihDD===',
        'guid=b61b9790083897515ead52b430fa7f7c; _ga=GA1.3.732902233.1639826279; acw_tc=2f624a3e16402705890986233e15eafe05670d10f2064fbb56641531540303; acw_sc__v2=61c48afdb72c254f7a8458401de17d24862a0d40; ssxmod_itna=eqGOGK4UrTD5GHvxCDjoxmrrjeyDitOiDcitD0yioeGzDAxn40iDtxosBiDprmEn5PEe47I3pQ8opqQL3EAW3KebPSife/GDB3DEx0=wAYxYYkDt4DTD34DYDixibhxi5GRD0FCDbxYpyDA3Di4D+zd=DmqG0DDt7/4G2D7Uyj0Y4zu0XWeNo6uYqqE=D0M=DjwbD/RAacnrF1pGVbo=DzMFDtTNlzLtox0PsR3wqGAvQ+73w=SDvaYezGi3v6Yqwi05dCBDKUUP3AA54DDf1iF4xD==; ssxmod_itna2=eqGOGK4UrTD5GHvxCDjoxmrrjeyDitOiDcmxnKS2OKDsp=DLBDQwQk9kIQidqRKlS9NOO3g+5hGYgaQmLkdXea9WAextirczlKGlGXXYuKnrbs8gSWLPH+dUP/BGXp8yPigC=NvBHC6vka=PHpWyCYSaiCEi+XaGNY3+dN9u=GEybZYIIqjvvAxSmvE5rNbP4/mfGhBuLWp2LZm38O0EveB+qFYwXPWqxOWqQ9p5iBRW8kOSHtmyHsPOiLgRbz/9bDuP9g6WIqC68RGnbllRW9h4Dw6dDLxG7M+iQiO005ebmO7hP4D=',
        'guid=b61b9790083897515ead52b430fa7f7c; _ga=GA1.3.732902233.1639826279; acw_tc=2f624a3e16402705890986233e15eafe05670d10f2064fbb56641531540303; acw_sc__v2=61c48afdb72c254f7a8458401de17d24862a0d40; ssxmod_itna=QqfO0IxUgGCYGQDXDnD+r8NWDQiPyh900eerKDsFADSxGKidDqxBmWQPDtCbizeBATrfGqR7Bi31kFrixhW3DpfxpW1lox0aDbqGkpRQxiicDCeDIDWeDiDG4Gm/4GtDpxG6yDm4i36xA3Di4D+8MQDmqG0DDUHS4G2D7U9bGw9Yjde6qbSKG0KFqDl8qDMmeGXKDcdOQcagAXWtqGyAPGu0uU9IqbDC2vLGG4oSx41mYfh5G4IaAxzmD3IND+xjG7Yti53If8W0DwzBDDAGil3eD===; ssxmod_itna2=QqfO0IxUgGCYGQDXDnD+r8NWDQiPyh900eexikApvDlrrxxj+PpQdrdvQiduWD0EchzFUxEp21FR2jY6qXI2qY=h3YnAyNGCbbBIcmqm6W2BRn8mCyb3oa3FMRC9Qy+l1wlQ8gltsmohF4C53FwXnnGiYK0K0j04tKAhuBhQdI24GixG2l4GcDiQXjAe4zwwYa10QaG4xD==',
        'guid=b61b9790083897515ead52b430fa7f7c; _ga=GA1.3.732902233.1639826279; acw_tc=2f624a3e16402705890986233e15eafe05670d10f2064fbb56641531540303; acw_sc__v2=61c48afdb72c254f7a8458401de17d24862a0d40; ssxmod_itna=QqAx9iDteDwpGCDzrD2YLYKiK0=jt++feoNQD/fDfr4iNDnD8x7YDvmma7QgFObnxcXx7F=0DfeYWrDbRtq7G44xW=Qox0aDbqGkq9GrQGGjxBYDQxAYDGDDPDogPD1D3qDkXxYPGW8qiaDGeDec9ODY5DhxDC00PDwx0C6OGW6rYHY85mn=DhijKDBcKD9ooDs=DfQnKwEU3qZhRODlF6DCKz9c9Ci4GdI7cKeYxNkWR3AiCxPnxeo0T5510KqWr2klDx1nhxknRPlQtDia2elmGDD=; ssxmod_itna2=QqAx9iDteDwpGCDzrD2YLYKiK0=jt++feoNG9tM9DBdOdx7ph3ABa9xg=I7d9=2S2kDG8D3QFpFqbFETtvK7r0O4mD8E+Rw1+h=BTFzcfCSRX=PHEBy0HLZckKGx28TlI68MrNU96Yhp384LgtficGMLD=BeDKwxFD7=DeTRvG+hez70eKGP5DpeoOBEe0nqYeD='

        ]
for i in work_href: # 一次coolie至多15次
    headers2 = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3880.400 QQBrowser/10.8.4554.400',
        'Accept-Encoding': 'gzip, deflate, br',
        'Cookie':cookie_j2[cookie_i]
    }

    if count_i % 8 == 1 :  # 输出为1,2,3,4,5,6,7,0为8次循环,一次cookie用8个网页
        cookie_i += 1
    if cookie_i == 1 :# 爬取5*count_i个岗位数据存入txt中
            break
    else:
        print("cookie_i={}".format(cookie_i))
        print('正在爬取第{}页,爬取网址:{}'.format(count_i,i)) # 循环网址
        count_i += 1
        time.sleep(5)
        response = session.get(url=i, headers=headers2)  # 模拟get请求 返回信息response对象
        html = response.text.encode('iso-8859-1').decode('gbk')
        # print(html)
        selector = parsel.Selector(html)
        str_list = selector.xpath(' //div[@class="bmsg job_msg inbox"]//p/text()').getall() # 获取职位信息标签获取
        str_info = '\n'.join(str_list)  # 列表 转换为字符串 \n划分
        print(str_info)
        print()
        f.write(str_info)
        f.write('\r\n')
print("工作职责写入成功")

 

5.3 职位数据分析输出扇形图、柱形图完整代码

 代码如下:
import pandas as pd
import matplotlib.pyplot as plt
#from 前程无忧_单网页爬取 import data
## 根据数据得到柱形图、扇形图
plt.rcParams['font.sans-serif']=['SimHei'] #显示中文标签
plt.rcParams['axes.unicode_minus'] = False
def ShowWorkArea (data,i,k,x_axle,y_axle):
    f = data+'/'+data+'_'+k+'分析表.csv'
    work = pd.read_csv(f, encoding='gbk', nrows=i)  # i为显示前几列
    # print(work.values)
    list1 = []
    list2 = []
    for o in work.values:
        list1 += [o[0]]
        list2 += [o[1]]
    plt.pie(x=list2,  labels=list1,  autopct='%1.1f%%'  ) # 绘图数据,添加标签,设置百分比的格式,这里保留一位小数
    plt.title(data+'_'+k+"分析扇形图")
    plt.savefig("D:/学习/东软/大三上期/脚本语言开发(陈汉斌)/yunxingDaiMa/招聘/" + data + '/'+data+'_'+k+"分析扇形图.png")  # 保存图片 #绝对路径
    # 显示图形
    plt.show()
    # x轴是招聘地区,y轴是招聘数量,让直方图排序显示,默认升序
    work.sort_values(by=y_axle,inplace=True,ascending = False)
    # 将直方图颜色统一设置为红色
    work.plot.bar(x=x_axle, y=y_axle, color='red')
    # 旋转X轴标签,让其横向写
    plt.xticks(rotation=360)
    j = str(i)
    plt.title(data+'_'+k+"分析柱形图")
    plt.savefig("D:/学习/东软/大三上期/脚本语言开发(陈汉斌)/yunxingDaiMa/招聘/"+data+'/'+data+'_'+k+"分析柱形图.png") #保存图片的绝对路径,读者根据自己的存储位置改
    plt.show()
def xinzi_analyze(data,k) :
    f = data+'/'+data+'_'+k+'分析表.csv'
    work = pd.read_csv(f, encoding='gbk')
    list = []
    for o in work.values:
        list += [o[3]]  #35-5/10=3
    d = (max(list)-min(list))/10           #分10组计算组距整除
    ls = [0,0,0,0,0,0,0,0,0,0]             #初始化列表ls,记录每组频数  L2标签为11组数据,每相邻两个组成一个标签,组成10个标签
    ls2=[min(list),min(list)+d*1,min(list)+d*2,min(list)+d*3,min(list)+d*4,min(list)+d*5,min(list)+d*6,min(list)+d*7,min(list)+d*8,min(list)+d*9,min(list)+d*10]
    # 创建标签ls3:
    ls3=[]
    for i in range(10):
        ch1 = [(str(round(ls2[i], 1))) + "k-" + (str(round(ls2[i + 1], 1)) + "k")]
        ls3 = ls3 + ch1
    for i in range(len(list)):      #在a中依次找出每组数据,并在ls中计数
        if list[i]   <= min(list)  + d * 1:
            ls[0] = ls[0] + 1
        elif list[i] <= min(list) + d * 2:
            ls[1] = ls[1] + 1
        elif list[i] <= min(list) + d * 3:
            ls[2] = ls[2] + 1
        elif list[i] <= min(list) + d * 4:
            ls[3] = ls[3] + 1
        elif list[i] <= min(list) + d * 5:
            ls[4] = ls[4] + 1
        elif list[i] <= min(list) + d * 6:
            ls[5] = ls[5] + 1
        elif list[i] <= min(list) + d * 7:
            ls[6] = ls[6] + 1
        elif list[i] <= min(list) + d * 8:
            ls[7] = ls[7] + 1
        elif list[i] <= min(list) + d * 9:
            ls[8] = ls[8] + 1
        elif list[i] <= min(list) + d * 10:
            ls[9] = ls[9] + 1
    plt.pie(x=ls, labels=ls3,  autopct='%1.1f%%'  )
    plt.axis("equal")#使之呈现“正圆”,默认扁圆
    plt.title(data+'_薪资分布扇形图')
    plt.savefig("D:/学习/东软/大三上期/脚本语言开发(陈汉斌)/yunxingDaiMa/招聘/" + data + '/' + data + "_薪资分析扇形图.png")  # 保存图片,绝对路径
    plt.show()
data = str(input("请输入查询的关键词:"))
#data = '人工智能'
#i = int(input("请输入查询的数量:"))
ShowWorkArea(data, 10, k="地区",x_axle="招聘地区",y_axle="招聘数量")  # 展示招聘职位地区分布
ShowWorkArea(data, 10, k="经验",x_axle="经验要求",y_axle="数量")  # 展示招聘职位地区分布
ShowWorkArea(data, 10, k="学历",x_axle="学历要求",y_axle="数量")  # 展示招聘职位地区分布
xinzi_analyze(data,k="薪资")
print("职位数据分析_画图运行成功!")

5.4 根据岗位职责的TXT文件分析输出词云

  代码如下:

import re # 正则表达式库
import matplotlib.pyplot as plt # 图像展示库
import collections # 词频统计库
import numpy as np # numpy数据处理库
from PIL import Image # 图像处理库
import jieba # 结巴分词
import wordcloud # 词云展示库
# 读取文件
data = str(input("请输入词云生成的关键词:"))
fn= open(data+"/"+"招聘_"+data + ".txt", encoding="utf-8")
#fn = open('article.txt',encoding = "utf-8") # 打开文件
string_data = fn.read() # 读出整个文件
fn.close() # 关闭文件
# 文本预处理
pattern = re.compile(u'\t|\n|\.|-|:|;|\)|\(|\?|"') # 义正则表达式匹配模式
string_data = re.sub(pattern, '', string_data) # 将符合模式的字符去除
# 文本分词
seg_list_exact = jieba.cut(string_data, cut_all = False) # 精确模式分词
object_list = []
remove_words = [u'', u'',u'', u'', u'随着', u'对于', u'',u'',u'',u'',u'',u' ',u'',u'',u'',u'',
                u'通常',u'如果',u'我们',u'需要',u'岗位',u'职责',u'',u'相关',u'工作',u'进行',u'行业',u'1',u'2',u'3',u'4'
                ,u'5',u'6',u'7',u'8',u'9',u'公司',u'/'] # 自定义去除词库
for word in seg_list_exact: # 循环读出每个分词
    if word not in remove_words: # 如果不在去除词库中
        object_list.append(word) # 分词追加到列表
# 词频统计
word_counts = collections.Counter(object_list) # 对分词做词频统计
word_counts_top10 = word_counts.most_common(10) # 获取前10最高频的词
#print (word_counts_top10) # 输出检查
# 词频展示
mask = np.array(Image.open('背景.jpg')) # 定义词频的背景,可自己网上下载一张纯白色背景图
wc = wordcloud.WordCloud(
    font_path='C:/Windows/Fonts/simhei.ttf', # 设置字体格式
    mask=mask, # 设置背景图
    max_words=100, # 最多显示词数
    max_font_size=100 # 字体最大值
)
wc.generate_from_frequencies(word_counts) # 从字典生成词云
image_colors = wordcloud.ImageColorGenerator(mask) # 从背景图建立颜色方案
wc.recolor(color_func=image_colors) # 将词云颜色设置为背景图方案
plt.imshow(wc) # 显示词云
plt.axis('off') # 关闭坐标轴
plt.savefig("D:/学习/东软/大三上期/脚本语言开发(陈汉斌)/yunxingDaiMa/招聘/"+data+'/'+data+'_岗位职责词云'+'.png') #保存图片  绝对路径
plt.show() # 显示图像

 

5.5 合并多个csv文件为同一个exeal表完整代码

  代码如下

 1 import os
 2 import xlwt
 3 import csv
 4 def write_execl(csvfile, xlsfile, workbook, sheetname):
 5     # 创建表名,添加一个workbook的对象
 6     sheet = workbook.add_sheet(sheetname)
 7     # 读取csv文件内容,写入表 目录皆为下一目录
 8     reader = csv.reader(open('./'+data+'/'+csvfile, 'r'))
 9     i = 0
10     for content in reader:
11         for j in range(len(content)):
12             sheet.write(i, j, content[j])
13             j += 1
14         i += 1
15 # 目标execl文件名
16 data = str(input("请输入合并的关键词:"))
17 xlsfile = './'+data+'.xls'
18 # 初始化workbook对象
19 workbook = xlwt.Workbook()
20 # 创建当前目录data目录下文件列表
21 filelist = sorted(os.listdir('./'+data+'/'))
22 #print(filelist)
23 for file in filelist:
24     # 匹配以csv结尾的文件
25     if file.endswith('.csv'):
26         # 匹配出表名
27         sheetname = file.replace('.csv', '')
28         # 使用函数将csv文件内容导入到execl
29         write_execl(file, xlsfile, workbook, sheetname)
30 workbook.save('./'+data+'/'+xlsfile)

6、运行效果

6.1 C语言关键字保存的csv

6.1.1 主要数据csv

        效果如图:

6.1.2 地区分析scv

        效果如图:

6.1.3 经验要求csv

        效果如图:

6.1.4 学历要求csv

        效果如图:

 

 

 

6.2 C语言关键字保存的数据库

         效果如图:

 

 

 

6.3 C语言关键字分析得到的分析图

        效果如图:

 

 

 

 

 

 

 

 

6.4 C语言关键字分析岗位职责TXT文件得到的词云图

 

 

6.5 C语言关键字分析合并csv得到的exeal

        效果如图:

 

 

 



免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM