前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >最新puppeteer爬虫boss直聘招聘公司及职位信息

最新puppeteer爬虫boss直聘招聘公司及职位信息

作者头像
Python疯子
发布2020-03-20 10:04:11
1.2K0
发布2020-03-20 10:04:11
举报
文章被收录于专栏:Python疯子Python疯子

失踪人口回归了!由于一直在爬虫,遇到的坑比较多,先大致汇报下

1、获取全国所有企业

2、通过企查查补充企业信息

3、爬虫boss直聘获取公司及职位信息

本次先说爬虫boss直聘

image

目的:

获取指定城市下的指定行业的招聘公司及招聘职位信息

image

****一、试错阶段****

尝试使用了requests,selenium,pyppeteer,发现都不能正常访问boss直聘,厉害了我的老板!

于是只能采用puppeteer,因第一次使用puppeteer,也是第一次使用nodejs,代码规范和操作可能多有不妥之处,请您见谅。

二、爬虫注意点

1、公司名称重名问题(去重问题):

搜索Python搜到了公司A,Java也搜到了公司A,那么我只需要从一个入口进来,就会将该公司下的所有职位获取,即获取了Python,就不用获取Java的

考虑到公司名称相同,地点不同的原因,就是两个公司招聘信息,

公司A,在北京招聘名称为公司A,在上海招聘也叫公司A

这里通过记录公司详情的URL进行记录。

本来是想通过redis进行记录去重,发现redis是回调函数,不满足需求,mysql也是,智能才去记录到文件的形式。

2、页面跳转问题

意图通过对页面的点击操作,进行一步步获取信息,但是在实践过程中发现,跳转后页面会一直处于加载的卡死状态。

最后选择了通过一步步获取url,单纯加载url的形式进行获取信息。

三、获取城市code

https://www.zhipin.com/job_detail/?query=Python&city=101010100&industry=&position=

1、通过访问boss直聘的url,发现城市是通过citycode定位的

代码语言:javascript
复制
// 城市与城市编码的转换
function main(city, job){

  // 汉字 转 拼音
  // var pinyin = require('fast-pinyin');
  // var output = pinyin(city);
  // var firstChar = output[0][0]
  // console.log("城市:" + output[0][0]);


  const originData = require('./city.json');

  let city_code = null

  if (city == "全国")
    { 
      city_code = "100010000";
    }
  else
    for (var province_info of originData){ 
        var subLevelModelList = province_info["subLevelModelList"]
        for (var city_info of subLevelModelList){ 
          if (city_info["name"] == city)
            city_code = city_info["code"];
          }
  }

  console.log("找到城市代码:" + city_code);
  get_company(city_code, job)

}

city.json:记录的是城市与城市code的对应关系,文件来自boss直聘请求文件

四、获取所有企业

Python数据分析实战

通过搜索访问,获取该地区该关键词的所有企业名称

代码语言:javascript
复制
var next_page;
async function get_company(city_code, key_words){
    console.log('crawler start to visit the target address');

    /* 爬虫的目标链接地址: boss*/
    var url = `https://www.zhipin.com/c${city_code}/?query=${key_words}&page=1&ka=page-1`;

  /* dumpio 是否将浏览器进程stdout和stderr导入到process.stdout和process.stderr中 */
  const browser = await puppeteer.launch({
    // headless:false,
    args: ['--no-sandbox'],
    dumpio: false,
    // args:['--proxy-server=http://47.98.154.206:3008']

  });
  const page = await browser.newPage();
  await page.evaluateOnNewDocument(() => {
         Object.defineProperty(navigator, 'webdriver', {
         get: () => undefined,
    });
 });

 // 该地区 该类别的所有公司
 var company_info = []

 while (url != null && url.length > 20){

    await page.goto(url, {
      waitUntil: 'networkidle2'
    });
    await sleep(0);

    const result = await page.evaluate(() => {
      let data = []; 
      let elements = document.querySelectorAll('#main > div > div.job-list > ul > li'); //获取所有的li 
      for (var element of elements){ // 循环 
          let title = element.querySelector('div > div.info-primary > div.info-company > div > h3 > a').innerHTML; 
          let url = element.querySelector('div > div.info-primary > div.info-company > div > h3 > a').href; //抓取链接(href)属性 

          data.push({title, url}); // 存入数组
      }

      return data;
      });

      for (var temp of result){ // 循环 
        company_info.push(temp); // 存入数组
      }

    //下一页
    let next_page;

    if (result.length < 30) 
      next_page = null;
    else
      var element_next_page = await page.$("#main > div > div.job-list > div.page > a.next");
      if (element_next_page)
        next_page = await page.$eval('#main > div > div.job-list > div.page > a.next', ele=>ele.href);
      else
        next_page = null

    url = next_page
 }

//  page.close();

// 获取搜索到的所有企业信息
  // 数组去重
  let new_company_info = deduplication(company_info)

五、公司的招聘信息

Python数据分析实战

通过获取所有公司详情后,同时也获取了该公司的所有招聘信息

image

image

代码语言:javascript
复制
company_all_job = company_url_value.replace("gongsi", "gongsir")
  company_all_job = company_all_job.split("?")[0] + "?ka=company-jobs"

  var company_job_urls = []

  while ( company_all_job != null && company_all_job.length > 19){

    await page2.goto(company_all_job, {
      waitUntil: 'networkidle2'
    });
    await sleep(0);

    job_count = await page2.$eval('#main > div.company-banner > div > div.company-tab > a.cur', ele=>ele.innerText);

    if (job_count.includes("(0)"))
     {
      console.log("在招职位为0")
      company_all_job = null
    }
    else
    {
      const jobs_urls = await page2.evaluate(() => {
        let data = []; 
        let elements = document.querySelectorAll('div.job-list >ul >li'); //获取所有的li 
        for (var element of elements){ // 循环 
            let url = element.querySelector('a').href; //抓取链接(href)属性 
            data.push(url); // 存入数组
        }

        return data;
        });

        for (var temp of jobs_urls){ // 循环 
          company_job_urls.push(temp); // 存入数组
        }

      //下一页
      let next_job;
      var job_next_page = null;
      job_next_page = await page2.$("#main > div.job-box.company-job > div.inner.home-inner > div.job-list > div > a.next");
      if (job_next_page)
        next_job = await page2.$eval('#main > div.job-box.company-job > div.inner.home-inner > div.job-list > div > a.next', ele=>ele.href);
      else
        next_job = null

      company_all_job = next_job
    }
     }

    console.log("职位信息:\n", company_job_urls)
    console.log("职位信息个数:\n", company_job_urls.length)

    page2.close()```

六、获取岗位信息及入库

Python数据分析实战

拿到具体岗位连接后,通过访问就可以直接获取岗位信息,代码就不附加了

信息入库采用的是mysql,在入库的时候,同样做了职位的url查重处理,如果已存在则不再存储,避免重复存储。

image

最后发现并不能获取所有相应信息,因为职位搜索只显示前10页,公司招聘职位只显示前30页。如有童鞋有解决办法,望留言讨论

上面是获取公司信息和职位信息,但公司信息简单,关键信息没有。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 2、页面跳转问题
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档