# Python数据挖掘-51job招聘信息 **Repository Path**: zhang_jie_lin/web_data_mining_mid_term ## Basic Information - **Project Name**: Python数据挖掘-51job招聘信息 - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2021-05-22 - **Last Updated**: 2024-01-23 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 项目介绍 用户可通过以下代码,批量查询制定关键词下的所有招聘信息,包括职位名称,薪资,工作地点等详细信息 * 功能—— * 首页 · 关键词搜索 * 搜索页 · 分类搜索【行业,职能,经验】 * 搜索页 · 翻页 * 详细页 · 内容 ## 首页 · 关键词搜索 ### 准备工作 ``` import pandas as pd from requests_html import HTMLSession import urllib.parse url = "https://www.51job.com/" headers = { } session = HTMLSession() r = session.get( url ) ``` ### 先拿出 url 分析一下,找出每条url的不同之处 ``` 行业_xpath = '//div[@class="hm container"]//div[@class="cn hlist"]//div[contains(@class,"e")]/a' 行业分类_url = [list(i.absolute_links)[0] for i in r.html.xpath(行业_xpath)] 行业名称 = r.html.xpath('//div[@class="hm container"]//div[@class="cn hlist"]//div[contains(@class,"e")]/a/span/text()') 行业分类_dict = {i:行业分类_url[k].split('?')[0].split(',') for k,i in enumerate(行业名称)} 行业分类_df = pd.DataFrame(行业分类_dict) ## 打印成表出来看看 ``` * 对比发现,只有第六行的数据不同 ### 开始生成url ``` def 关键字查询(i): 参数模版 = urllib.parse.urlparse(行业分类_url[0])# 随便拿一条url进行拆分 参数模版_字符串 = str(参数模版) # print(参数模版) url = 参数模版.scheme+'://'+参数模版.netloc+"/list/030200,000000,0000,32,9,99,"+i+',2,1.html?'+参数模版.query return(url) ``` * 这个网站页面的关键字查询设置的非常简易,仅将用户输入的关键词插入到链接中的某个固定位置即可。 ## 搜索页 · 分类搜索 ### 前期准备 ``` import pandas as pd from requests_html import HTMLSession import urllib.parse url = "https://search.51job.com/" headers = { } session = HTMLSession() r = session.get( url ) ``` ### 特殊情况 · 网页含有js文件 * 面对动态加载网页,不能直接提出xpath,需找到对应的js文件 * 此处对scr进行拼接,直接生成网页链接 ``` msg = "http:"+r.html.xpath('//script')[-3].html.split("\"")[3] import requests res = requests.get(msg) 参数 = res.content.decode("gbk","ignore") ``` ### 行业分类 #### 形成分类字典 ``` 行业分类 = {"01":"计算机软件",37:"计算机硬件",38:"计算机服务(系统、数据服务、维修)",31:"通信/电信/网络设备",39:"通信/电信运营、增值服务",32:"互联网/电子商务",40:"网络游戏","02":"电子技术/半导体/集成电路",35:"仪器仪表/工业自动化",41:"会计/审计","03":"金融/投资/证券",42:"银行",43:"保险",62:"信托/担保/拍卖/典当","04":"贸易/进出口",22:"批发/零售","05":"快速消费品(食品、饮料、化妆品)","06":"服装/纺织/皮革",44:"家具/家电/玩具/礼品",60:"奢侈品/收藏品/工艺品/珠宝",45:"办公用品及设备",14:"机械/设备/重工",33:"汽车",65:"汽车零配件","08":"制药/生物工程",46:"医疗/护理/卫生",47:"医疗设备/器械",12:"广告",48:"公关/市场推广/会展",49:"影视/媒体/艺术/文化传播",13:"文字媒体/出版",15:"印刷/包装/造纸",26:"房地产","09":"建筑/建材/工程",50:"家居/室内设计/装潢",51:"物业管理/商业中心",34:"中介服务",63:"租赁服务","07":"专业服务(咨询、人力资源、财会)",59:"外包服务",52:"检测,认证",18:"法律",23:"教育/培训/院校",24:"学术/科研",11:"餐饮业",53:"酒店/旅游",17:"娱乐/休闲/体育",54:"美容/保健",27:"生活服务",21:"交通/运输/物流",55:"航天/航空",19:"石油/化工/矿产/地质",16:"采掘业/冶炼",36:"电气/电力/水利",61:"新能源",56:"原材料和加工",28:"政府/公共事业",57:"非营利组织",20:"环保",29:"农/林/牧/渔",58:"多元化业务集团公司"} ``` * json文件的好处就是,数据结构和存放清晰。 #### 参数构建 ``` 行业_参数构建 = {v:k for k,v in 行业分类.items()} ``` * 通过循环调换 key 和 value 的位置,方便我们后面的处理 ### 职能分类 * 职能与行业用相似方法,同样形成分类字典 ### 经验分类 #### 形成字典 * 通过观察,我们发现经验、薪资等的排列方式与刚才的行业和职能不太一样 * 这时,我们先用split拆分出经验的段落 ``` 经验 = 参数.split("window.d_search_workyear=")[1].split(",window.d_search_providesalary=")[0] ``` #### 数据处理 ``` 经验replace = 经验.replace('k:"','').replace('",v:"','=').replace("{","").replace('"}','').replace('[','').replace(']','') 经验split = 经验replace.split(',') ``` * 新建一个薪资_str的字典,这里我们可以将“请选择”改为“所有” ``` 经验_str = ["所有","在校生/应届生","1-3年","5-10年","05=10年以上","无需经验"] 经验_dict = {i:经验split[k].split('=')[0] for k,i in enumerate(经验_str)} ``` #### 对比链接 ``` URL1 = "https://search.51job.com/list/000000,000000,0100,03,9,03,%25E8%25BF%2590%25E8%2590%25A5,2,1.html?lang=c&postchannel=0000&workyear=99&cotype=99°reefrom=99&jobterm=99&companysize=99&ord_field=0&dibiaoid=0&line=&welfare=" URL2 = "https://search.51job.com/list/000000,000000,0100,03,9,10,%25E8%25BF%2590%25E8%2590%25A5,2,1.html?lang=c&postchannel=0000&workyear=99&cotype=99°reefrom=99&jobterm=99&companysize=99&ord_field=0&dibiaoid=0&line=&welfare=" URL1 = URL1.split("?")[0].split(',') URL2 = URL2.split("?")[0].split(',') 比较 = pd.concat([pd.Series(URL1),pd.Series(URL2)],axis=1) 比较[5:6] ``` * 对比发现,只有第五行的数据不同 #### 构建参数模板 ``` 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=" 参数模版 = urllib.parse.urlparse(url) 参数模版_list = pd.Series(参数模版).tolist() 参数模版_dict = {i.split("=")[0]:i.split("=")[1] for i in 参数模版.query.split("&")} 参数模版_dict_1 = 参数模版_list[2].split(",") display(参数模版_list) display(参数模版_dict) display(参数模版_dict_1) ``` #### 封装 ``` def url_参数模板生成(industry,career,salary,keyword): industry_values = 行业_参数构建[industry] career_values = 职能_参数构建[career] salary_values = 经验_dict[salary] keyword_values = urllib.parse.quote(keyword) 参数模版_dict_1[3] = industry_values 参数模版_dict_1[2] = career_values 参数模版_dict_1[5] = salary_values 参数模版_dict_1[6] = keyword_values final_dict = ",".join(参数模版_dict_1) 参数模版_list[2] = final_dict url_参数 = urllib.parse.urlunparse(参数模版_list) return (url_参数) ``` ## 爬取数据以及翻页 ### 解析网页 ``` session = HTMLSession() r = session.get(final_url) ``` * 根据__SEARCH_RESULT__找到需要的数据 ``` __SEARCH_RESULT__ = r.html.xpath('//script')[-4].html.split('__SEARCH_RESULT__ = ')[1].split('')[0] results = eval(__SEARCH_RESULT__) ``` ### 找到总页数信息 ``` total_page = results['total_page'] ``` ### 循环生成url ``` url_split = final_url.split(',') page_url_split = final_url.split(',')[8].split('.') url_group = [] for i in range(1,int(total_page)+1): page_url_split[0] = str(i) url_split[8] = ".".join(page_url_split) url_complete = ",".join(url_split) url_group.append(url_complete) url_group ``` ### 爬取信息 ``` list_df = [] for i in (url_group): r = session.get(i) __SEARCH_RESULT__ = r.html.xpath('//script')[-4].html.split('__SEARCH_RESULT__ = ')[1].split('')[0] results = eval(__SEARCH_RESULT__) df = pd.DataFrame(results['engine_search_result'])[['job_name','company_name','job_href','attribute_text','companyind_text','issuedate']] list_df.append(df) df_all = pd.concat(list_df) df_all.head() ``` ### 修改链接,使之成为可直接打开的外链格式 ``` url_all = list(df_all['job_href']) url_all url_detail = [] for i in url_all: j = i.replace('\\',"") # 替换掉所有连接的反斜杠 url_detail.append(j) url_detail ``` ### 重新替换列表 ``` df_all['job_href'] = url_detail ``` ### 保存 ``` with pd.ExcelWriter('51job.xlsx',mode='w',engine="openpyxl") as writer: df_all.to_excel(writer, sheet_name='岗位信息') ``` ## 爬取详细页内容 * 循环每一个详细页面链接提取出详细页面的职位,职位信息,薪资 ``` 职位 = [] 职位信息 = [] 薪资 = [] for i in url_detail: session = HTMLSession() r = session.get(i) 职位.append(r.html.xpath('//div[@class="cn"]/h1/@title')) 职位信息.append(r.html.xpath('//div[@class="bmsg job_msg inbox"]/p/text()')) 薪资.append(r.html.xpath('//div[@class="cn"]/strong/text()')) detail = pd.DataFrame({ "职位":职位, "职位信息":职位信息, "薪资":薪资, }) detail ``` * 存入详细信息 ``` with pd.ExcelWriter('51job.xlsx',mode='a',engine="openpyxl") as writer: detail.to_excel(writer, sheet_name='岗位详细信息') ```