python爬取广西人才网招聘信息并可视化

python爬取广西人才网招聘信息并可视化,第1张

概述对要爬取的数据进行分析要爬取的网页:https://s.gxrc.com/sJob?district=1&pageSize=20&orderType=0&listValue=1.html我们需要爬取的信息有9个维度,分别是:职位,名称,公司名称,薪资,工作地,更新时间,学历,经验,岗位要求。职位信息的爬取格式如上图所示,但是如果我们规定了某一个关键 对要爬取的数据进行分析

要爬取的网页:https://s.gxrc.com/sJob?district=1&pageSize=20&orderType=0&ListValue=1.HTML
我们需要爬取的信息有9个维度,分别是:职位,名称,公司名称,薪资,工作地,更新时间,学历,经验,岗位要求。


职位信息的爬取格式如上图所示,但是如果我们规定了某一个关键字(key)后,信息格式会变成


会出现<span class='highlight>的标志,这样对数据的爬取有不小的限制,所以采取另一种方案。
进一步观察,可以得到图一中,href后的链接为我们需要的岗位描述以及经验、学历、岗位名称。如下图:


岗位名称就在标签</h1 titile="">内,而学历,经验等信息都在v1的标签之内:

可以注意到岗位描述在标签

ID="examineSensitiveWordsContent"内,这里可以用BeautifulSoup直接获取text即可,其他的数据全部用正则匹配即可出来(我是能用正则就用正则)
至于公司名称,薪资,工作地,更新时间信息,在第一个页面都能获取到。

翻页分析

点开第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爬取广西人才网招聘信息并可视化所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/langs/1187595.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-03
下一篇 2022-06-03

发表评论

登录后才能评论

评论列表(0条)

保存