Python爬虫-简历解析
本科生简历分析
- 实验知识点
- 实验步骤
- 实验效果图
- 实验代码
实验用到的是Python爬虫技术,实现爬取和可视化的思想有:
实验知识点
使用request.get(url)获取网页的HTML。
对返回回来的HTML代码进行正则表达式匹配提取网页中需要的数据和文本。
正则表达式:re 模块使 Python 语言拥有全部的正则表达式功能。
Python 的 re 模块提供了re.sub用于替换字符串中的匹配项。
re.sub(pattern, repl, string, count=0, flags=0)
参数:pattern : 正则中的模式字符串。
repl : 替换的字符串,也可为一个函数。
string : 要被查找替换的原始字符串。
count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。
compile 函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象。该对象拥有一系列方法用于正则表达式匹配和替换。
re.compile(pattern[, flags])
参数:pattern : 一个字符串形式的正则表达式
flags : 可选,表示匹配模式,比如忽略大小写,多行模式等,具体参数为:
re.I 忽略大小写
re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境
re.M 多行模式
re.S 即为 . 并且包括换行符在内的任意字符(. 不包括换行符)
re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依赖于 Unicode 字符属性数据库
re.X 为了增加可读性,忽略空格和 # 后面的注释
Findall 在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。
findall(string[, pos[, endpos]])参数:
string : 待匹配的字符串。
pos : 可选参数,指定字符串的起始位置,默认为 0。
endpos : 可选参数,指定字符串的结束位置,默认为字符串的长度。使用字典保存提取到的想要的数据。
把提取到的信息保存到XLS文件中(Excel):
用到的是xlwt模块,xlwt.workbook(encoding=‘utf-8’)去创建保存的编码格式,使用workbook.add_sheet()去创建XLS表,使用worksheet.write()对表进行填写,然后在用for循环把提取到的内容按创建的表头,正确的填入对于的列中。精确提取个人经历,并且用AGraph对其进行可视化出来,思维导图显示个人经历;用到for循环去处理第一次提取出来的粗糙数据,把数据分别保存在变量中,再对这些数据进行思维导图的实现。
实验步骤
爬取简历:
粗糙爬取部分代码展示
分析心得:遇到蛮多坑的,提取不到数据,提取到的数据为空,匹配不准确,HTML中包含一些特殊字符,需要去排除,或者后期把特殊字符删掉,比如空格字符,乱码,其他无关字符;还有正则表达式的书写,这是最难的一点,需要写得和返回的HTML相匹配,而不是在网页控制台上的,会有一些出入。
保存为xls部分代码
分析心得:由于数据比较多,在保持代码上就会看起来很多,特别是判断信息是否是在该列上,难道不大,就是比较繁琐。
数据可视化部分代码
分析心得:这在前面已经有过可视化的实现,这次就做的比较轻松一些,但是也有新的内容,就是在节点旁边添加附加的标注,这个我也是找了很久,找到了又存在和别用的可视化方法不同,label的设置调了很久。
实验效果图
实验代码
#实验三提取简历要素
import requests
import xlwt
import re
import os
import pygraphviz as pgvdef get_hdxw_all_report(url):dic = {}r = requests.get(url)#返回网页所有内容r.encoding = "gbk"#编码r.raise_for_status()#判别返回response类型状态,返回200正确否则会错误matches = "x"matches = re.findall('<td width="100".*?>姓名</td> <td .*?>(.*?)</td>',r.text)#不带括号为非匹配内容,匹配到的所有内容放到一个列表中#['姓名','-']# a=matches.group(1) 报错AttributeError: 'list' object has no attribute 'group'# print(matches)dic['姓名'] = matchesmatches = re.findall('<td .*?> 国籍:</td> <td .*?>(.*?)</td>',r.text)#中间的空格是需要的,相当于HTML换行dic['国籍'] = matches[0]matches = re.findall('<td .*?> 目前所在地:</td> <td .*?>(.*?)</td>',r.text)dic['目前所在地'] = matches[0]matches = re.findall('<td .*?> 民族:</td> <td .*?>(.*?)</td>',r.text)dic['民族'] = matches[0]matches = re.findall('<td .*?> 户口所在地:</td> <td .*?>(.*?)</td>',r.text)dic['户口所在地'] = matches[0]matches = re.findall('<td .*?> 身材:</td> <td .*?>(.*?)</td> </tr>',r.text)a = matches[0]#matches 30行会出现错误,# strinfo = re.compile('')#创建模式对象# b = strinfo.sub('', a)a = a.replace(' ', ' ')#a = a.replace('��', ' ')#用''代替'��'dic['身材'] = amatches = re.findall('<td .*?> 婚姻状况:</td> <td .*?>(.*?)</td>',r.text)dic['婚姻状况'] = matches[0]matches = re.findall('<td .*?>年龄:</td> <td .*?>(.*?)</td>',r.text)dic['年龄'] = matches[0]matches = re.findall('<td .*?>培训认证:</td> <td .*?>(.*?)</td>',r.text)a = matches[0] #提取出来是&nbs;strinfo = re.compile(' ||;|| ')#创建' '对象b = strinfo.sub('', a)# 空格处理# a=re.sub(' ','',a)也可以处理&nbsq空格,但是显示占位大dic['培训认证'] = bmatches = re.findall('<td .*?>诚信徽章:</td> <td .*?>(.*?)</td>',r.text)a = matches[0]strinfo = re.compile(' ||;|| ')b = strinfo.sub('', a)dic['诚信徽章'] = bmatches = re.findall('<td .*?>人才类型:</td> <td .*?>(.*?)</td> ',r.text)a = matches[0]strinfo = re.compile('')b = strinfo.sub('', a)b = b.replace('��', ' ')b = b.replace(' ', ' ')dic['人才类型'] = bmatches = re.findall('<td .*?>应聘职位:</td> <td .*?>(.*?)</td> ',r.text)a = matches[0]strinfo = re.compile('\u3000')b = strinfo.sub('', a)#a中用''替换'\u3000'dic['应聘职位'] = bmatches = re.findall('<td .*?> 工作年限:</td> <td width="180">(.*?)</td>',r.text)dic['工作年限'] = matches[0]matches = re.findall('<td .*?> 职称:</td> <td>(.*?)</td>',r.text)dic['职称'] = matches[0]matches = re.findall(' <td .*?> 求职类型:</td> <td .*?>(.*?)</td>',r.text)dic['求职类型'] = matches[0]matches = re.findall('<td .*?> 可到职-</td> <td>(.*?)</td>',r.text)dic['可到职'] = matches[0]matches = re.findall('<td .*?> 月薪要求:</td> <td .*?>(.*?)</td>',r.text)dic['月薪要求'] = matches[0]matches = re.findall('<td .*?> 希望工作地区:</td> <td nowrap>(.*?)</td>',r.text)dic['希望工作地区'] = matches[0]matches = re.findall('<td .*?>个人工作经历:</td> <td colspan="3">(.*?)</td>',r.text)a = matches[0]strinfo = re.compile('  ||  ||<br>')b = strinfo.sub('', a)dic['个人工作经历'] = bmatches = re.findall('<td .*?> 毕业院校:</td> <td .*?>(.*?)</td>',r.text)dic['毕业院校'] = matches[0]matches = re.findall(' <td .*?> 最高学历:</td> <td width="180">(.*?)</td>',r.text)dic['最高学历'] = matches[0]matches = re.findall(' <td .*?> 毕业-</td> <td>(.*?)</td>',r.text)dic['毕业'] = matches[0]matches = re.findall('<td .*?> 所学专业一:</td> <td width="180">(.*?)</td>',r.text)dic['所学专业一'] = matches[0]matches = re.findall('<td .*?> 所学专业二:</td> <td>(.*?)</td>',r.text)dic['所学专业二'] = matches[0]matches = re.findall('<td .*?> 受教育培训经历:</td> <td colspan="3">(.*?)</td>',r.text)a = matches[0]strinfo = re.compile('<br\s*?/?>|| ||;||\u3000')b = strinfo.sub('', a)dic['受教育培训经历'] = bmatches = re.findall('<td width="100" align="right" bgcolor="#EEF4F9"> 外语:</td> <td width="180" bgcolor="#F4F7FA">(.*?)</td>',r.text)a = matches[0]strinfo = re.compile('<br\s*?/?>|| ||\u3000')b = strinfo.sub('', a)dic['外语'] = bmatches = re.findall('<td align="right" bgcolor="#EEF4F9"> 国语水平:</td> <td bgcolor="#F4F7FA">(.*?)</td>',r.text)dic['国语水平'] = matches[0]matches = re.findall('<td align="right" bgcolor="#EEF4F9" width="100"> 粤语水平:</td> <td bgcolor="#F4F7FA">(.*?)</td>', r.text)dic['粤语水平'] = matches[0]matches = re.findall('<td bgcolor="E4EBF2" height="18"><b> 工作能力及其他专长</b></td> </tr> </table> <table width="580" border="0" cellspacing="1" cellpadding="2" bgcolor="#CADADF" align="center"> <tr> <td width="100" bgcolor="#EEF4F9"></td> <td bgcolor="#F4F7FA">(.*?) </td>',r.text)a = matches[0]strinfo = re.compile('</?\w+[^>]*>|| || ')b = strinfo.sub('', a)dic['工作能力及其他专长'] = bmatches = re.findall('<b> 详细个人自传</b></td> </tr> </table> <table width="580" border="0" cellspacing="1" cellpadding="2" bgcolor="#CADADF" align="center"> <tr> <td width="100" bgcolor="#EEF4F9"></td> <td bgcolor="#F4F7FA">(.*?)</td>',r.text)a = matches[0]strinfo = re.compile('</?\w+[^>]*>|| ||;|| ')b = strinfo.sub('', a)dic['详细个人自传'] = bprint(dic)#输出dic{}#存为xls(excel)workbook = xlwt.Workbook(encoding='utf-8')worksheet = workbook.add_sheet('sheet1')# 设置表头worksheet.write(0, 0, label='姓名')worksheet.write(0, 1, label='国籍')worksheet.write(0, 2, label='目前所在地')worksheet.write(0, 3, label='民族')worksheet.write(0, 4, label='户口所在地')worksheet.write(0, 5, label='身材')worksheet.write(0, 6, label='婚姻状况')worksheet.write(0, 7, label='年龄')worksheet.write(0, 8, label='培训认证')worksheet.write(0, 9, label='诚信徽章')# ----------------------------------worksheet.write(0, 10, label='人才类型')worksheet.write(0, 11, label='应聘职位')worksheet.write(0, 12, label='工作年限')worksheet.write(0, 13, label='职称')worksheet.write(0, 14, label='求职类型')worksheet.write(0, 15, label='可到职')worksheet.write(0, 16, label='月薪要求')worksheet.write(0, 17, label='希望工作地区')worksheet.write(0, 18, label='个人工作经历')worksheet.write(0, 19, label='毕业院校')# ----------------------------worksheet.write(0, 20, label='最高学历')worksheet.write(0, 21, label='毕业')worksheet.write(0, 22, label='所学专业一')worksheet.write(0, 23, label='所学专业二')worksheet.write(0, 24, label='受教育培训经历')worksheet.write(0, 25, label='外语')worksheet.write(0, 26, label='国语水平')worksheet.write(0, 27, label='粤语水平')worksheet.write(0, 28, label='工作能力及其他专长')worksheet.write(0, 29, label='详细个人自传')flag = os.path.exists("OK.xls")val = 1if flag is False:for key in dic:if key == '姓名':worksheet.write(val, 0, dic.get(key))if key == '国籍':worksheet.write(val, 1, dic.get(key))if key == '目前所在地':worksheet.write(val, 2, dic.get(key))if key == '民族':worksheet.write(val, 3, dic.get(key))if key == '户口所在地':worksheet.write(val, 4, dic.get(key))if key == '身材':worksheet.write(val, 5, dic.get(key))if key == '婚姻状况':worksheet.write(val, 6, dic.get(key))if key == '年龄':worksheet.write(val, 7, dic.get(key))if key == '培训认证':worksheet.write(val, 8, dic.get(key))if key == '诚信徽章':worksheet.write(val, 9, dic.get(key))if key == '人才类型':worksheet.write(val, 10, dic.get(key))if key == '应聘职位':worksheet.write(val, 11, dic.get(key))if key == '工作年限':worksheet.write(val, 12, dic.get(key))if key == '职称':worksheet.write(val, 13, dic.get(key))if key == '求职类型':worksheet.write(val, 14, dic.get(key))if key == '可到职':worksheet.write(val, 15, dic.get(key))if key == '月薪要求':worksheet.write(val, 16, dic.get(key))if key == '希望工作地区':worksheet.write(val, 17, dic.get(key))if key == '个人工作经历':worksheet.write(val, 18, dic.get(key))if key == '毕业院校':worksheet.write(val, 19, dic.get(key))if key == '最高学历':worksheet.write(val, 20, dic.get(key))if key == '毕业':worksheet.write(val, 21, dic.get(key))if key == '所学专业一':worksheet.write(val, 22, dic.get(key))if key == '所学专业二':worksheet.write(val, 23, dic.get(key))if key == '受教育培训经历':worksheet.write(val, 24, dic.get(key))if key == '外语':worksheet.write(val, 25, dic.get(key))if key == '国语水平':worksheet.write(val, 26, dic.get(key))if key == '粤语水平':worksheet.write(val, 27, dic.get(key))if key == '工作能力及其他专长':worksheet.write(val, 28, dic.get(key))if key == '详细个人自传':worksheet.write(val, 29, dic.get(key))#如果再爬一个网站就要修改一下文件workbook.save('OK.xls')return dic#求职意向及工作经历,教育背景
def get_time_thing(who):b=who['个人工作经历']c=who['受教育培训经历']#匹配时间和文字#pattern=re.compile()#数字范围\u0030-\u0039 中文范围\u4e00-\u9fa5# it = re.finditer(r"\d+",c)# for i in it:# ctime[i]=match.group()for each in who:if '-'or'.' in each:pattern = re.compile(r'\d+[.-]\d+[.-]\d+[.-]\d+') # ['','']类型或返回空else:pattern = re.compile(r'\d+')str_content = re.compile('[\u4e00-\u9fa5][^0-9]+')#中文范围\u4e00-\u9fa5必要前面时间可能有.-btime = pattern.findall(b)bstar = str_content.findall(b)ctime = pattern.findall(c)cstar = str_content.findall(c)# print(b)# print(c)print(btime)print(bstar)print(ctime)print(cstar)# 有向图 非简单图,不同级节点最小间距,线条类型,合并线条G = pgv.AGraph(directed=True, strict=False, ranksep=0.2, splines='spline', concenyrate=True, rounded=True,expected=2, fontname="FangSong", encoding='UTF-8')G.graph_attr['epsilon'] = '0.001'alongs = len(cstar) # 长度for i in range(alongs): # 不能直接alongs进行迭代TypeError: 'int' object is not iterable# 添加节点G.add_node(cstar[i],color='#ffffff', fontname="FangSong", fontsize=18,encoding='UTF-8')# 添加边G.add_edge('start',cstar[0], color='#7F01FF', arrowsize=0.8,label=ctime[0])G.add_edge([cstar[0], cstar[1]],color='#7F01FF', arrowsize=0.8,label=ctime[1])G.add_edge([cstar[1], cstar[2]],color='#7F01FF', arrowsize=0.8,label=ctime[2])G.layout()G.draw("简历提取要素3.png", prog="dot") # 乱码解决,节点指定字体,保存为utf-8next_url = "http://www.gerenjianli.com/resume/class/11749.htm" #11746、11749、11750测试成功。
a=get_hdxw_all_report(next_url)
b=get_hdxw_all_report("http://www.gerenjianli.com/resume/class/11746.htm")
c=get_hdxw_all_report("http://www.gerenjianli.com/resume/class/11750.htm")
#经历
get_time_thing(c)
#get_time_thing(a)
Python爬虫-简历解析相关推荐
- python爬虫正则表达式实例-python爬虫 正则表达式解析
这篇文章主要介绍了python爬虫 正则表达式解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 - re.I # 忽略大小写 - re.M # 多 ...
- python简介怎么写-python爬虫简历怎么写
python爬虫简历怎么写? python爬虫简历如下: 1. 基本信息 求职岗位:Python爬虫工程师(全职) 期望薪资:15000以上 姓名:xx 手机号码:xxxx 邮箱:xxxx@qq.co ...
- 硬核来袭!!!一篇文章教你入门Python爬虫网页解析神器——BeautifulSoup详细讲解
文章目录 一.BeautifulSoup介绍 二.安装 三.bs4数据解析的原理 四.bs4 常用的方法和属性 1.BeautifulSoup构建 1.1 通过字符串构建 1.2 从文件加载 2.Be ...
- python爬虫数据解析总结
python爬虫数据解析总结 目录 python爬虫数据解析总结 1.概述 2.Xpath解析html数据 2.1.基本语法 1.查询语法 2.2.Xpath解析html数据 1.安装lxml库 2. ...
- python爬虫案例-python爬虫详细解析附案例
什么是爬虫框架 说这个之前,得先说说什么是框架: 是实现业界标准的组件规范:比如众所周知的MVC开发规范 提供规范所要求之基础功能的软件产品:比如Django框架就是MVC的开发框架,但它还提供了其他 ...
- Python爬虫笔记——解析json数据(以周杰伦歌单为例)及Headers
一.Network Network能够记录浏览器的所有请求.我们最常用的是:ALL(查看全部)/XHR(仅查看XHR)/Doc(Document,第0个请求一般在这里),有时候也会看看:Img(仅查看 ...
- python爬虫lxml解析爬取诗词名句
原创:仅用于学习Python爬虫,请勿商业或恶意爬取数据 文件夹和文件都是程序创建,我只爬了这些数据用于测试 仅用了两个for循环,并没有搞的太难(函数),适合新手操练,有大量注释易于理解 from ...
- python爬虫五大解析器
python有五大解析器 一.正则表达式 ,使用第三方库 re(re) 1.匹配规则有 模式 描述 \w 匹配字母.数字及下划线 \W 匹配不是字母.数字及下划线的字符 \s 匹配任意空白字符,等价 ...
- python 爬虫智能化解析
爬虫是做什么的?是帮助我们来快速获取有效信息的.然而做过爬虫的人都知道,解析是个麻烦事. 比如一篇新闻吧,链接是这个:https://news.ifeng.com/c/7kQcQG2peWU,页面预览 ...
最新文章
- jquery validate使用
- Python之基础知识
- JVM 常用参数一览表(转)
- UGUI_使用DoTween
- 《软件测试技术》课程第二周随笔
- alibaba fastJson框架快速解析复杂有重复性质的json
- 阿里 P8 员工招聘私人助理被辞退;微信上线「拍一拍」功能;FreeBSD 11.4 释出 | 极客头条...
- mysql 二进制 查询_MySql如何插入和查询二进制数据_MySQL
- php指定时间 n天,PHP实现指定时间的n月之前的这一天的两种算法
- 几种平均数的物理意义应用场景
- html文本特效代码逐个出现,JS特效文字逐个显示
- 一个简单的BitTorrent客户端实现(三):同步事件分离器
- Ceph 集群监控之Calamari 安装部署
- input输入框限制(座机,手机号码)
- 【机器学习】有监督、无监督、自监督、半监督、弱监督的区别
- AFL学习笔记(下)
- 湘大1218 A+BVIII
- 微信公众号怎么添加外链
- 乐刻运动 app android,乐刻运动app_乐刻运动手机最新版v1.0
- 手机获取验证码的功能