目录
5.2 职位详情网页爬取完整代码
5.3 职位数据分析输出扇形图、柱形图完整代码
5.4 根据岗位职责的TXT文件分析输出词云
5.5 合并多个csv文件为同一个exeal表完整代码
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为:
其中: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°reefrom=99&jobterm=99&companysize=99&ord_field=0&dibiaoid=0&line=&welfare=
#代表其他的如工作城市、月薪范围的检索,我们保持不变
代码如下:
4.1.2 定义data、以及分析数据所需要的列表、变量
代码如下:
4.1.3 创建py相对路劲下的data文件夹
先判断是否又此文件夹,没有则创建,此处path用的绝对路径。
代码如下:
4.1.4 打开csv文件,并写入表头
此处ANSI为css的exeal编码,utf-8为txt编码。css编码不懂得可参考一下网址:
代码如下:
4.1.5 根据输入数据的data创建数据库的表名
数据库的表名必须为全英文,不能为中文,所以需要定义is_Chinese函数,判断输入的data是否为中文,是中文根据输入的中文转换为拼音,不是则数据库名为'job_zhiwei_' + data。如输入:大数据,返回job_zhiwei_ dsj;输入prthon,则返回job_zhiwei_python,如果c//或者带有/*|\等符号的会报错,且网址也检索不出来。但是C++是网址有效检索数据,作为数据库表名则不行,有兴趣的可以自己完善下此代码,可将C++转换为C__,这中有效数据。
输入阿里巴巴,输出数据库名效果如图:
此函数参考网址
代码如下:
4.1.6 链接数据库,写入数据库表头
代码根据输入的data,创建不同的数据库表名;其中数据库的host为本地数据库,一般为127.0.0.1,也可为localhost;port为端口;databa为数据库;charset='utf8'为设置字符编码为utf8。
创建后表头效果如图:
代码如下:
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为阿里巴巴 数据库存储效果如下:
参考代码如下:
4.3 数据分析
4.3.1 薪资分析
(1)薪资字符串切分并转换为不同的4个列表
在薪资分析时有多个干扰字符串,如1.5千以下/月、100万以上/年这种薪资不便于计算,空的的薪资、时薪、日薪的不在参考范围,这类数据需要排除;此代码在有薪资全部基本信息的循环下。
根据切分后输出的四个列表效果如图:
参考代码如下:
(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函数
列表统计转换字典后效果如图:
经验要求图;
学历要求图:
地区划分图:
函数定义参考代码如下:
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文件效果如图:
此子项目完整代码如下:
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°reefrom=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("工作职责写入成功")
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
效果如图: