58招聘数据爬取准备: 源码分析

通过各种点击观察,发现58同城的URL构造挺特殊的。
根据互联网协议和规则,一般查询参数都直接在cgi后加参数,如cgi?key=abc&page=1这样的。
但是58喜欢赶潮,除了关键词key之外,一些重要的查询参数(职业、行业、页码等)都在URL的目录中构造,而不是作为参数。这个技术我不太懂-_-!,大概是服务器对URL进行分析再获取参数吧,这个不重要。
(注:我是用python开发,刚入门,目前正在用BeautifulSoup扩展,所以经常提到一些相关术语。另外,定位方法我建议采用CSS选择器,语法是通用的。)

招聘搜索页源码分析

下面是我将几乎全部搜索条件都加上的全链接:
*http://bj.58.com/haidian/tech/pve_5363_244_pve_5754_1476_pve_5356_6_pve_5357_6/?key=%E6%95%B0%E6%8D%AE&minxinzi=3000_4999&postdate=20151209_20151216¶m6693=8&PGTID=0d303655-0047-792b-50b1-e40ba04c7e85&ClickID=1 *
好的,根据这个链接,以及各种尝试出来的判断,URL的结论如下:

  • 第一部分:子域名。bj.58.com,其中bj作为城市范围的“参数值”。值得一提的是,58同城没有省级分区,全都是针对某个城市。
  • 第二部分:目录参数。以下按目录固定顺序排列:
    1. /haidian/即海淀区,代表了地区或地点“参数值”,还可以是/wudaokou/五道口、/beijingdaxue/北京大学等,还可以是/beijingzhoubian/北京周边,都是区域那一栏所有选项的中文全拼。如果是现实全北京的数据的话,这个目录参数是被省略的的
    2. /tech/即职位类别为"计算机/互联网"类。这一部分有点意思,如果改成/job/就会不限分类,显示所有结果;如果改成/chengxuyuan/则会显示"程序员"的子职业分类。也就是说,58不区分各种职业的层级关系,也不考虑多选——要么全选要么单选。
    3. pve_5363_244_pve_5754_1476_pve_5356_6_pve_5357_6 这个是看起来最复杂的,但是稍微留意下也好理解,其实是——“更多”栏的筛选项,一般有四种参数在这里显示,每种之间用下划线连接,如果没有选择的话这里就不显示其值。其中pve_$$$$_??是固定格式,$$$$是4位数字代表参数名,后面的??是1~4位是不固定的数字代表参数值。
      • pve_5363:公司行业代号。后面的244是“计算机/互联网行业”。合在一起代表“公司行业为计算机及互联网行业”。
      • pve_5754:公司性质代号。后面的1476代表“私营”企业。
      • pve_5356:学历要求代号。后面的6代表“本科”。
      • pve_5357:经验要求代号。后面的6代表“3年-5年”。
  • 第三部分:查询参数。这里就没有固定顺序了。
    • params6693:福利待遇。如果值是1,代表五险一金;6代表周末双休。不可多选!
    • minixinzi:薪资范围。如0_9993000_4999等。

页码:

页码超出搜索结果的总页码时,会显示省略号。
但是结果再多,也只能显示到70页,和智联招聘差不多(到90页)。

包含招聘结果的大框架

页面唯一重要的列表信息,都包括在了这个框架中:

一条招聘信息

框架定位关键是

id="infolist",而结果列表中每一条的定位关键为
标签包含logr属性,且规律为logr="p_?_????_ses^composite??"

逐行结果的代码解析

每一条信息的源码如下(量比较大):

数据处理员
山东正元数字城市建设有限公司麻...
北京
12-13

其中,一条信息的确认方式有3中:

  • dl [logr]dl [sortid]dl [_pos],合并定位
  • input [name="uid"]
  • div class="xboxcontent"div class="tipsbox"合并定位

获取每条招聘信息的基本内容

  1. 企业ID:定位在
  • uid:定位在
  • 职位名称及职位详情页URL:
数据处理员` 

需要注意的是,详情url尽量结合hrefurlparams参数一起构造,不过不放在一起也无所谓。

  • 企业名称:定位在

    山东正元数字城市建设有限公司麻城项目

  • 招聘职位:查找语法是-> ul[class*=zhanshi] li nth-of-type(1) 或者不用nth-of-type()语法,而是按文本匹配。
  • 招聘人数:查找语法是-> ul[class*=zhanshi] li nth-of-type(2) 或者不用nth-of-type()语法,而是按文本匹配。
  • 工作经验:查找语法是-> ul[class*=zhanshi] li nth-of-type(3) 或者不用nth-of-type()语法,而是按文本匹配。
  • 学历要求:查找语法是-> ul[class*=zhanshi] li nth-of-type(4) 或者不用nth-of-type()语法,而是按文本匹配。
  • 转正工资:查找语法是-> ul[class*=zhanshi] li nth-of-type(5) 或者不用nth-of-type()语法,而是按文本匹配。
  • 职位描述:查找语法是-> ul[class*=zhanshi] + p
  • 企业名称及链接:定位在以下代码中。注意企业名称才用title属性中的,而不是被阉割的文本处。
xxxx有限公司...
`
  • 工作地点:
    北京
  • 发布日期:
    12-13

判断是否为推广信息

如果一行信息内包括这条,那么就是推广信息:

精准

通过标签的class="tuiguang"来定位。
如果是正常消息,则没有这个链接,且只显示文本的“今天”或者是“12-12”这种具体日期。

获取当前页码及下一页链接

这一步其实是非常重要的!直接关系到是否抓瞎。
首先,58的设置是这样的:
58最多只显示70页信息,每页45条。强行打开70页以上的页面,或者超过当前结果的总页数,都会显示新信息较少,我们为您推荐以下相关信息:
我们先来看源码,然后再处理。


从上面我们可以这样得到些信息:

  1. 上一页链接:div[class="pagerout"] a[class="prv"],获取其href属性值就好了。如果没有,表示正在第一页。
  • 下一页链接:div[class="pagerout"] a[class="next"],获取其href属性值就好了。如果没有,表示正在最后一页。
  • 当前页码:div[class="pagerout"] div[class="pager"] strong,当前页是不带链接的,所以要这样获取。

判断搜索结果是否读完

通过测试发现,根据结果数量的不同,除了正常外汇产生以下结果:

  1. 显示新信息较少,我们为您推荐以下相关信息:一般是因为超过了应有的页码了。这样的信息通过源码找到
    新信息较少,我们为您推荐以下相关信息:
    就可以了。
  2. 显示很抱歉,没有找到符合已选条件的信息。\n建议您:,这是因为搜索条件太苛刻没有符合条件的。这样的,通过源码找到:

很抱歉,没有找到符合已选条件的信息。
建议您:

招聘详细页源码分析

这个页面比较简单,除了企业联系方式是动态加载的图片外都比较好定位抓取。不过联系方式也对我没什么太大用就不费那功夫了。

精简招聘信息

是被包含在头文件中用来给搜索引擎搜索用的,所以是精华中的精华哈哈。如下:


只要通过定位,获取其content属性值`就好了。

获取招聘基本信息

所有的信息都包含在了

...
框架中。能够找到的信息如下:

  1. 职位名称:

写累了,直接上BeautifulSoup格式的css选择器的查找语法,分别为:
所在行业 =div[class*=compMsg] ul li a[href]找到,
企业性质 = div[class*=compMsg] ul li nth-of-type(2),
企业规模 = div[class*=compMsg] ul li nth-of-type(3)或者li[class="scale"],
入驻时间 = div[class*=compMsg] ul li nth-of-type(4)li[class="joinday"]

获取联系信息

都包含在这个div中:

...

然后可以找到这些信息:

  1. 联系人:王经理 (联系我时请说明是在58同城上看到的),定位方法:div[class="conTip"]
  • 工作地点:源码有点长,定位方法:只能用文字匹配了,找到
    工作地址:
    这2个标签,它们
    中间的标签就是地址。
  • 卫星定位:其实也不用费劲,直接找到a[class="map"],获取其href然后用增则表达式匹配2个116.337795这种数字,就得到精确坐标了。源码如下:
查看地图

获取企业介绍

企业信息都包含在这里面:

...

定位方式为:直接div[class="compIntro"]#gongsi获取所有文字内容就是企业介绍了。

企业主页源码分析

58还真是方便,再牛的企业都是一模一样的简单网页。不过还好,这也方便获取数据了。
这个页面极其简单,但是有一点需要注意,数据是用表格动态呈现的,每种信息的位置并不固定,是根据企业有没有这个信息才显示出来的。所以在信息定位上,尽量避免用序号,只能用中文匹配了。。需要获取的数据如下:

  1. 卫星定位:在头文件中,如。找到获取coord属性值就好了。
  • 企业名称及ID:div[class="compT"] a[href]就可以找到企业名称,在href属性中的是/ID/这样的格式,去掉/就好了。
  • 企业资质:最好在div[class="basicMsg"] tr中用文字匹配。
  • 企业性质:最好在div[class="basicMsg"] tr中用文字匹配。
  • 企业行业:最好在div[class="basicMsg"] tr中用文字匹配。
  • 企业规模:最好在div[class="basicMsg"] tr中用文字匹配。
  • 联系人: 最好在div[class="basicMsg"] tr中用文字匹配。
  • 联系电话:用文字匹配或[class="telNum"] img,注意,联系电话都是图片格式的,而且可以不止一个!(省事的话就别下载图片了,保存链接就好了,因为图片来源明显不是静态图片而是服务器动态生成的。)
  • 企业网址(自己的):最好在div[class="basicMsg"] tr a中或用文字匹配。
  • 企业邮箱:和电话一样,用文字匹配或[class="telNum"] img来找图片。
  • 公司地址:最好在div[class="basicMsg"] tr中用文字匹配。

企业信用档案页面URL及源码分析

这个页面不知道入口在哪里?偶然看到的,然后心里大呼——哇塞!哈哈
虽然找不到入口或者查询页面,但是发现其实看懂URL就很简单了,必要格式如下:
http://credit.vip.58.com/usercredit?userId=企业ID
那么这时候刚才获取的企业ID就起作用了。手工输入了一下,ID对的话每家企业都能出来。
建立了档案的企业——会显示巨详细的信息!连法人代表、注册资本、详细地址全都有。
没建立档案的企业——也会显示页面,但信息处全都是空白。
下面就简单分析下基本信息的获取。

获取企业营业执照信息

表格基本上是固定位置的,因为大家营业执照都一样嘛哈哈~
首先获取信息框架:div[class="zzxx_ta"] table,然后再到这个框架里操作,就简单多了。
下面是信息定位分析:

  1. 公司名称:td[class="tdbg"] + td的第1项或span[class="headTitle"]
  • 注册号:td[class="tdbg"] + td的第2项
  • 经营地址:td[class="tdbg"] + td的第3项
  • 注册资本:td[class="tdbg"] + td的第4项
  • 成立日期:td[class="tdbg"] + td的第5项
  • 法定代表人:td[class="tdbg"] + td第6项
  • 登记机关:td[class="tdbg"] + td的第7项
  • 企业类型:td[class="tdbg"] + td的第8项
  • 营业期限:td[class="tdbg"] + td的第9项
  • 核准日期:td[class="tdbg"] + td的第10项
  • 登记状态:td[class="tdbg"] + td的第11项
  • 在营(开业)企业:td[class="tdbg"] + td的第12项
  • 经营范围:td[class="tdbg"] + td的第13项

获取企业其他信息

  1. 企业简介:div[class="briefIntro"]
  • 企业图片:div[class="albumBox"] img
  • 企业抽查检查信息:div[class="zzxx_ta"] nth-of-type(1) tr,如果有记录则显示,无记录则只显示一条“无xx信息”。可以适当排除。
  • 企业经营异常信息:div[class="zzxx_ta"] nth-of-type(2) tr,如果有记录则显示,无记录则只显示一条“无xx信息”。可以适当排除。
  • 企业行政处罚信息:div[class="zzxx_ta"] nth-of-type(3) tr,如果有记录则显示,无记录则只显示一条“无xx信息”。可以适当排除。
  • 企业严重违法信息:div[class="zzxx_ta"] nth-of-type(4) tr,如果有记录则显示,无记录则只显示一条“无xx信息”。可以适当排除。

你可能感兴趣的:(58招聘数据爬取准备: 源码分析)