一开始必须要解析智联招聘搜索列表页,从这里更方便实现各种深层级数据抓取。
网页地址是:
http://sou.zhaopin.com/jobs/searchresult.ashx
智联招聘的服务器只接收Get方式,如果用Post方式抓取页面,则不会返回想要的招聘信息,而会得到一堆广告。
下面是我手动测试的一些智联在这个页面Get方式传递的搜索参数,也是目前最常用的(注释掉的不怎么常用):
data_filter = {
\'kw\' : keyword, # 搜索关键词
\'sm\' : \'0\', # 显示方式代码: 列表是\'0\',详细是\'1\'。显示不同源码也不同,尽量选列表模式,源码更好解析。
\'jl\' : \'北京\', # 搜索城市:\'北京\',多项用\'+\'连接(URL编码为%2B)
#\'bj\' : \'\', # 职位类别代码:互联网产品/运营管理 的代码为 \'160200\',多项用\'%3B\'连接(URL编码的%)
#\'in\' : \'\', # 行业代码:多项用\';\'连接(URL编码为%3B)
\'kt\' : \'0\', # 关键词搜索范围:全文\'0\' | 公司名\'1\' | 职位名\'2\'
\'isadv\' : \'0\', # 是否高级搜索:快速搜索\'0\' | 高级搜索\'1\'
# \'isfilter\' : \'1\', # 是不是筛选器: \'0\' | \'1\'
# \'ispts\' : \'\', # 通常为 \'1\'
#\'sj\' : \'\', # 职位子类别代码:
# \'gc\' : \'5号\', # 地铁线路: \'5号\'
# \'ga\' : \'立水桥\', # 地名或地铁站名: \'天通苑南\' 、 \'小汤山\'
# \'sb\' : \'0\', # 排序方式代码:默认排序是\'0\',相关度排序是\'1\', 首发日排序是\'2\'
#\'fjt\' : \'10000\', # 职位标签 五险一金\'10000\' 年底双薪\'10001\' 绩效奖金\'10002\' 等等
# \'sf\' : \'-1\', # 月薪底线:\'8001\' 不限是\'-1\'
# \'st\' : \'-1\', # 月薪上限:\'10000\' 不限是\'-1\'
# \'ct\' : \'-1\', # 公司性质代码
# \'el\' : \'-1\', # 学历代码
# \'we\' : \'-1\', # 工作经验代码
# \'et\' : \'-1\', # 职位类型代码:兼职\'1\' 全职\'2\' 实习\'4\'
# \'pd\' : \'-1\', # 发布时间(天数):一周是\'7\',一个月是\'30\',不限是\'-1\'
\'p\' : page, # 页码,超出总页码时,则会显示最后一页
#\'gr\' : \'\', #
# \'re\' : \'2015\', # 这个限制了搜素数量,但是其实也不是按年份搜索
\'sg\' : guid, # 即全网唯一标示符——GUID
#\'\' : \'\' #
}
它在python中的用法,就是通过urllib.urlencode()来转成URL参数格式,并提交。
如果解析“列表模式”的智联招聘网页,需要在Get参数里面的sm设为0
。
里面唯一需要的就是中间的结果列表部分,
即id为\’newlist_list_content_table\’的DIV用,源码如下:
一条招聘信息
一条招聘信息
其中会循环输出class为newlist
的Table表格
即一条一条的招聘信息。
每一条招聘信息的源码如下:
87%
中海软银投资管理有限公司
面议
北京
12-10
在“列表”模式中,每一条记录采用了Table格式,第一个TR是简述信息,第二个TR是扩展信息。简述信息中,每个信息都有固定Class属性,而且是非空信息,是肯定能获取到的。而扩展信息中,规则性不强,只能用“公司性质:xx”这样的正则表达式来匹配或是用tag的嵌套层级和顺序来定位,成功率和稳定性都不高。
总结一下,这里的主要定位方式为:
职位名称: class = \"zwmc\"
反馈率 : class = \"fk_lv\"
公司名称: class = \"gsmc\"
职位月薪: class = \"zwyx\"
或 职位月薪:xx
工作地点: class = \"gzdd\"
或 地点:xx
更新时间: 12-10class = \"gxsj\"
或
公司性质: 公司性质:xx
公司规模: 公司规模:xx
学历要求: 学历:xx
岗位职责:
其实还有tag的嵌套层级和顺序,可以用来定位信息。但是我不想这么做,因为这个太不稳定了,而且大大的增加了代码的长度,如果不存在信息还会导致报错。相比而言,用中文的人能理解的语言来进行正则匹配,更有成功率,且更容易操作。
如果解析“详细模式”的智联招聘网页,需要在Get参数里面的sm设为1
。
里面唯一需要的就是中间的结果列表部分,
即id为\’newlist_list_content_table\’的DIV用,源码如下:
一条招聘信息
一条招聘信息
其中会循环输出class为newlist_detail newlist
的子DIV层
即一条一条的招聘信息。
每一条招聘信息的源码如下:
-
乐视网信息技术(北京)股份有限公司
-
地点:北京
公司性质:上市公司
公司规模:1000-9999人
学历:本科
-
岗位职责: 1、负责对日常行政后勤工作(包括名片、加班餐、办公用品、员工离入职、印章、会议室的相关事宜)进行全面的监督控制,发现问题及时予以规范,协助上级领导应对处理突发事件; 2、进行行政后勤各项费用预算,严格管控各项费用的使用情况,节省公司成本,实现效益的最大化; 3、部门员工的招聘与培养和...
在源码上,虽然“详细模式”的解析和“列表模式”有很大的不同,几个信息的抓取方式不一样,但是却可以共用。如有的是按照class名,有的是按照tag名等。但是这不影响两种模式放在一起解析——为每一个信息元素如“月薪”、“公司名称”等,设置多种搜索方式。在写代码时,只要分别检索多种方式就可以获得数据。具体参考抓取代码的实现。
虽然每页只能显示40条信息,但是在页面上方还是会显示一共有多少条搜索结果。如“”
代码如下:
共2025个职位满足条件
虽然没有研究过GUID,但是我看到智联招聘的网页会在URL中显示的调用,参数名为sg
。
不知道它对爬虫有什么影响。不过我还是尝试着获取了一下,很简单直接用id搜索input标签的value就行。网页源码如下:
智联招聘这个页面最逗的是,如果当前信息只有4页,那么及时url参数中页码指定100,它仍然不会自动跳转。所以从url或者.geturl()
来判断当前真实页码也就成了不对了。
不过好在一点,这个页面下方的页码控制栏
中可以清楚的看到当前页码是多少,所以就从这里入手。这部分网页源码如下:
从中可以看到,当前页码的定位极其方便,只要从class=\"pagesDown\"
的div中找到class=\"current\"
的a链接就得到了。
同理,下一页的链接可以找class=\"next-page\"
的a标签获取href值。