失踪人口回归了!由于一直在爬虫,遇到的坑比较多,先大致汇报下
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也是,智能才去记录到文件的形式。
意图通过对页面的点击操作,进行一步步获取信息,但是在实践过程中发现,跳转后页面会一直处于加载的卡死状态。
最后选择了通过一步步获取url,单纯加载url的形式进行获取信息。
三、获取城市code
https://www.zhipin.com/job_detail/?query=Python&city=101010100&industry=&position=
1、通过访问boss直聘的url,发现城市是通过citycode定位的
// 城市与城市编码的转换
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数据分析实战
通过搜索访问,获取该地区该关键词的所有企业名称
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
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页。如有童鞋有解决办法,望留言讨论
上面是获取公司信息和职位信息,但公司信息简单,关键信息没有。