要爬取的网页:https://s.gxrc.com/sJob?district=1&pageSize=20&orderType=0&ListValue=1.HTML
我们需要爬取的信息有9个维度,分别是:职位,名称,公司名称,薪资,工作地,更新时间,学历,经验,岗位要求。
进一步观察,可以得到图一中,href后的链接为我们需要的岗位描述以及经验、学历、岗位名称。如下图:
可以注意到岗位描述在标签
至于公司名称,薪资,工作地,更新时间信息,在第一个页面都能获取到。
翻页分析
点开第2页,可以得到地址栏的变化为:
https://s.gxrc.com/sJob?district=1&pageSize=20&orderType=0&ListValue=1.hml&keyword=信息管理&page=2
pageSize、ListValue信息不用处理,只需要处理keywork与page两个信息即可,page明显是翻页处理的,keyword则是查询的关键字。
python代码# -*- Coding:utf-8 -*-import requestsimport reimport timefrom openpyxl import Workbookfrom bs4 import BeautifulSoupkey_word = '信息管理' # 查询的关键字#获取原码信息def getContent(page): url = 'https://s.gxrc.com/sJob?district=1&pageSize=20&orderType=0&ListValue=1.hml'+'.hml&keyword={}&page={}'.format(key_word, page) HTML = requests.get(url).content.decode("utf-8") # 获取网页信息 return HTMLdef getInfo(HTML, ws): '''一页信息有20个''' job_name, job_edu, job_expe, job_requirement = [], [], [], [] # 岗位名字,学历, 经验, 岗位要求都是列表形式存放 ent_name = re.findall(r'>(.*?)</a>', HTML) # 公司名字 price = re.findall(r'<li >(.*?)</li>', HTML)[1:] # 薪资 city = re.findall(r'<li >(.*?)</li>', HTML)[1:] # 工作地 refresh_time = re.findall(r'<li >(.*?)</li>', HTML)[1:] # 更新时间 deatil_info_url = re.findall(r'<a href="//(.*?)" target="_blank" >', HTML) # 详细信息的页面网址,用于爬取职位要求和描述 for url in deatil_info_url: url = "https://"+url HTML = requests.get(url).content.decode('utf-8') # 进一步解析网页的信息,获得职位名称和岗位要求两个信息 name = re.findall(r'<h1 title="(.*?)">', HTML)[0] # 只有一个 edu = re.findall(r'</span>学历(.*?)<span >', HTML)[0] # 学历 expe = re.findall(r'</span>经验(.*?)<span >', HTML)[0] # 经验 soup = BeautifulSoup(HTML, "HTML.parser") # 正则无法完全匹配岗位要求,所以采用BeautifulSoup requirement = soup.find(ID='examineSensitiveWordsContent').text # 岗位要求 job_name.append(name) job_edu.append(edu) job_expe.append(expe) job_requirement.append(requirement) for i in range(0, 20): ws.append([job_name[i], ent_name[i], price[i], city[i], refresh_time[i], job_edu[i], job_expe[i], job_requirement[i]])def main(): # 页码和对应着的文件名字次数,以防读写卡死 Title = ['职位名称','公司名称', '薪资','工作地','更新时间','学历','经验 ','岗位要求'] # 写入到excel的标题,可以更改 wb = Workbook() ws = wb[wb.sheetnames[0]] ws.append(Title) # 写入标题头到excel去 save_@R_403_6852@ = '{}.xlsx'.format(key_word) # 以搜索的关键字作为excel的名字 total_page = 480 # 最大页码数 for page in range(1, total_page+1): # 获取490页的内容 try: print("正在爬取第{}页".format(page)) HTML = getContent(page) # 一页一页获取数据 if page % 10 == 0: # 爬到了10的倍数,暂停2s time.sleep(2) getInfo(HTML, ws) # 传入一页的页面信息和对应的表格去 except Exception as e: print(e) wb.save(save_@R_403_6852@) # 将爬到的数据写入到excel去 wb.save(save_@R_403_6852@)if __name__ == '__main__': main()
数据可视化在测试的时候,注意到爬取速度比较慢,于是尝试用多进程爬取,爬取太快导致ip被封了,那就只能单线程爬取了,并且我还设定了2s暂停一下,全部爬取完大概在30分钟左右,总共有
9728
条信息(在关键字信息管理的条件下)
数据可视化的代码大多差不多,就不分析如何写的了,贴在下面:
from openpyxl import load_workbookimport matplotlib.pyplot as pltimport numpy as npimport matplotlibimport wordcloudimport reimport jIEba # 分词jIEba库matplotlib.rcParams['Font.sans-serif'] = ['SimHei'] # 汉字matplotlib.rcParams['axes.unicode_minus'] = Falseclass DrawingPicture: def __int__(self): self.excel_@R_403_6852@ # excle文本数据 self.city_txt_@R_403_6852@ # 城市文本数据 self.wb # excel内的表格数据 self.ws self.Font # 指定中文字体 def get@R_403_6852@(self,excel, txt = ''): # 获取文本数据 self.excel_@R_403_6852@ = excel self.city_txt_@R_403_6852@= txt self.wb = load_workbook(self.excel_@R_403_6852@) self.ws = self.wb[self.wb.sheetnames[0]] # 获取第一个sheet self.Font = r'C:\windows\Fonts\simfang.ttf' # 必须要下一个simfang.tff文字库,安装到C:\windows\Fonts def getWorldCouldPic(self): text = "" for i in range(2, self.ws.max_row+1): text += self.ws['A'+str(i)].value + " " w = wordcloud.WordCloud(background_color="WHITE", Font_path = self.Font, stopwords=['南宁','桂林','柳州'],) # 可根据需要添加要不考虑的词语 w.generate(" ".join(jIEba.lcut(text))) w.to_@R_403_6852@("岗位词云图.png") def getSalaryPic(self): salary_num = {} for i in range(2, self.ws.max_row+1): salary = self.ws['C'+str(i)].value if salary != ' ': # 不考虑空值 if salary not in salary_num.keys(): # 计算薪水 salary_num[salary] = 1 else: salary_num[salary] += 1 # 如果有,则加1 if None in salary_num.keys(): # 删除None值 del salary_num[None] sorted(salary_num.keys()) labels = np.array(List(salary_num.keys())) total = 0 for i in salary_num.values(): total += i sizes_pre = [round((x/total*100), 2) for x in List(salary_num.values())] plt.barh(range(len(salary_num)), sizes_pre, height=0.6, color='steelblue', Alpha=0.8) plt.yticks(range(len(salary_num)), List(salary_num.keys())) plt.xlabel("百分比") plt.Title("薪资占比条形图") for x, y in enumerate(sizes_pre): plt.text(y + 0.2, x - 0.1, '%s' % y) plt.savefig("薪水分布条形图.png", dpi = 200, bBox_inches ='tight') plt.close() def getFreshTimePic(self): time_dict = {} # 年-月对应的数字 for i in range(2, self.ws.max_row+1): time = self.ws['E'+str(i)].value if time != ' ': month = re.findall(r'(\d{4}-\d{2})', time)[0] # 获取年份-月份数据 year = re.findall(r'\d{4}', month)[0] if int(year) not in [x for x in range(2016, 2020, 1)]: # 不考率2019年之前的数据 if month in List(time_dict.keys()): # 如果在要寻找的列表内 time_dict[month] += 1 else: time_dict[month] = 1 temp_dict = sorted(time_dict.items(), key=lambda item:item[0]) time_dict.clear() for d in temp_dict: # 按照时间顺序来排序 time_dict[d[0]] = d[1] month = List(time_dict.keys()) # print(month) plt.plot(month, List(time_dict.values()), label='信息管理与信息系统月份职位数', ) plt.xticks(rotation=30) # 将更坐标旋转30度 plt.xlabel("年-月份") interval = 400 # 以400为一个间隔 y_ticks = np.arange(0, max(List(time_dict.values()))+ interval, interval) # 参数说明: 起始位置, 结束位置(这里以数据的最大值+一个间隔为最大值), 间隔数 plt.yticks(y_ticks) for a, b in zip(List(time_dict.keys()), List(time_dict.values())): plt.text(a, b, b, ha='center', va ='bottom', Fontsize=10) plt.legend() # plt.show() plt.savefig("岗位数量变化折线图.png", dpi = 200, bBox_inches='tight') plt.close() def getEduPic(self): edu_dict = {} for i in range(2, self.ws.max_row+1): edu = self.ws['F'+str(i)].value if edu != ' ': if edu not in edu_dict.keys(): edu_dict[edu] = 1 else: edu_dict[edu] += 1 total = 0 for i in edu_dict.values(): total += i name_pre = [] for edu, num in edu_dict.items(): name_pre.append(edu + str(round(num/total*100, 2)) +'%') # 名字+占比 # plt.close() plt.barh(range(len(edu_dict)), edu_dict.values(), height=0.7, color='steelblue', Alpha=0.8) plt.yticks(range(len(edu_dict)), edu_dict.keys()) plt.xlabel('数量') plt.Title('企业对学历要求') for x, y in enumerate(edu_dict.values()): plt.text(y/2, x-0.1, '%s' % y) # plt.text(y + 30, x - 0.1, '%s' % name_pre[x]) # 此行代码显示百分比 plt.savefig("学历要求条形图.png", dpi = 200, bBox_inches='tight') # plt.show() plt.close() def getExpPic(self): exp_dict = {} for i in range(2, self.ws.max_row+1): exp = self.ws['G'+str(i)].value if exp != ' ': if exp not in exp_dict: exp_dict[exp] = 1 else: exp_dict[exp] += 1 total = 0 for i in exp_dict.values(): total += i name_pre = [] for exp, num in exp_dict.items(): name_pre.append(str(round(num / total * 100, 2)) + '%') # 名字+占比 plt.barh(range(len(exp_dict)), exp_dict.values(), height=0.7, color='steelblue', Alpha=0.8) plt.yticks(range(len(exp_dict)), exp_dict.keys()) plt.xlabel('次数') plt.Title('企业对经验要求') for x, y in enumerate(exp_dict.values()): plt.text(y / 3, x - 0.1, '%s' % y) plt.text(y + 10, x - 0.1, '-->%s' % name_pre[x]) # plt.show() plt.savefig("企业对经验要求条形图.png", dpi=200, bBox_inches='tight') plt.close() def getWordCouldRequirePic(self): # 岗位要求词云图 text = "" for i in range(2, self.ws.max_row+1): text += self.ws['H' + str(i)].value + " " w = wordcloud.WordCloud(background_color="WHITE", Font_path = self.Font, stopwords=['及','良好','的','和','与','等']).generate(" ".join(jIEba.lcut(text))) w.to_@R_403_6852@("岗位要求词云图.png") def getPlacePic(self): # 获取岗位所在地区数量图 area_place = {} place_num = {} # 城市:数量 字典关系变量 with open(self.city_txt_@R_403_6852@, "r", enCoding='utf-8') as f: text = f.read() all_info = re.findall(r'[^=\s]+', text) for p in range(0, len(all_info)-1, 2): area_place[all_info[p+1]] = all_info[p] place_num[all_info[p]] = 0 for i in range(2, self.ws.max_row+1): place = self.ws['D' + str(i)].value for v in area_place.keys(): if place in v: chinese = re.findall(r'"(.*?)"', v)[0] place_num[chinese] += 1 break plt.bar(range(len(place_num)), List(place_num.values()), align='center', Alpha=0.7, wIDth=0.7) plt.xticks(range(len(place_num)), List(place_num.keys()), rotation='vertical') plt.ylabel('个数') plt.xlabel("城市") plt.Title('信息管理与信息系统岗位工作分布条形图') for x, y in enumerate(place_num.values()): plt.text(x-0.3, y, '%s' % y) plt.savefig("信息管理与信息系统岗位工作分布条形图.png", dpi=200, bBox_inches='tight') plt.close() def main(): ''' 如果没有城市数据,则get@R_403_6852@第二个参数不用设置,并且getPlacePic方法不用 ''' demo = DrawingPicture() # demo.get@R_403_6852@("./信息管理.xlsx", "./城市分布.txt" ) # excel数据 与 城市文本数据,绝对路径 demo.get@R_403_6852@("./信息管理.xlsx") demo.getWorldCouldPic() # 岗位名称次元图 demo.getSalaryPic() # 薪水 demo.getFreshTimePic() # 更新时间(岗位数量 demo.getEduPic() # 学历 demo.getExpPic() # 经验 demo.getWordCouldRequirePic() #岗位要求词云 # demo.getPlacePic() # 地区if __name__ == '__main__': main()
城市分布数据是按照如下的数据格式来的:
列表内的数据都考虑在赋值号左侧对应的城市数据内 总结
以上是内存溢出为你收集整理的python爬取广西人才网招聘信息并可视化全部内容,希望文章能够帮你解决python爬取广西人才网招聘信息并可视化所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)