爬虫的基本思路

1、在前程无忧官网检索“大数据”的结果中,每条检索结果详情对应的URL存在a标签的href属性中,通过组合选择器可以找到每条检索结果详情的URL。

2、前程无忧的招聘岗位信息数据固定的放在HTML的各个标签内,通过id选择器、标签选择器和组合选择器可以诸如公司名、岗位名称和薪资等11个字段的数据。

3、基于上述1和2,可以通过解析检索“大数据”得到的URL得到其HTML,再从此HTML中的具体位置的a标签得到每个岗位的详情对应的URL;然后解析每个岗位的详情对应的URL得到其HTML,再从结果HTML的具体位置找到每个岗位的详情。具体位置怎么确定呢?通过组合选择器!

前程无忧爬虫具体代码

SpiderOf51job.py

import requests
from lxml import etree
import csv
import time
import random
'''
更多Python学习资料以及源码教程资料,可以在群1136201545免费获取
'''
fp = open('51job.csv', 'wt', newline='', encoding='GBK', errors='ignore')
writer = csv.writer(fp)
'''title,salary,company,companyinfo,companyplace,place,exp,edu,num,time,info'''
writer.writerow(('职位', '薪资', '公司', '公司信息', '公司地址', '地区', '工作经验', '学历', '人数', '时间', '岗位信息'))

def parseInfo(url):

    headers = {
        'User-Agent': 'Opera/9.80 (Android 2.3.4; Linux; Opera Mobi/ADR-1301071546) Presto/2.11.355 Version/12.10'
    }#更换请求头,防止被反爬虫
    res = requests.get(url, headers=headers)
    res.encoding = 'utf-8'

    selector = etree.HTML(res.text)

    title = selector.xpath('//*[@id="pageContent"]/div[1]/div[1]/p/text()')
    salary = selector.xpath('//*[@id="pageContent"]/div[1]/p/text()')
    company = selector.xpath('//*[@id="pageContent"]/div[2]/a[1]/p/text()')
    companyinfo = selector.xpath('//*[@id="pageContent"]/div[2]/a[1]/div/text()')
    companyplace = selector.xpath('//*[@id="pageContent"]/div[2]/a[2]/span/text()')
    place = selector.xpath('//*[@id="pageContent"]/div[1]/div[1]/em/text()')
    exp = selector.xpath('//*[@id="pageContent"]/div[1]/div[2]/span[2]/text()')
    edu = selector.xpath('//*[@id="pageContent"]/div[1]/div[2]/span[3]/text()')
    num = selector.xpath('//*[@id="pageContent"]/div[1]/div[2]/span[1]/text()')
    time = selector.xpath('//*[@id="pageContent"]/div[1]/div[1]/span/text()')
    info = selector.xpath('string(//*[@id="pageContent"]/div[3]/div[2]/article)')
    #类选择器解析URL中对应HTML对应的字段内容
    info = str(info).strip()

    print(title, salary, company, companyinfo, companyplace, place, exp, edu, num, time, info)
    writer.writerow((title, salary, company, companyinfo, companyplace, place, exp, edu, num, time, info))


def getUrl(url):
    print('New page')
    res = requests.get(url)
    res.encoding = 'GBK'
    # print(res.text)
    if res.status_code == requests.codes.ok:
        selector = etree.HTML(res.text)
        urls = selector.xpath('//*[@id="resultList"]/div/p/span/a/@href')
        #                      //*[@id="resultList"]/div/p/span/a
        # id选择器找到当前网页每一个职位a标签对应的当前岗位具体信息URL列表
        print(urls)
        for url in urls:
            parseInfo(url)
            time.sleep(random.randrange(1, 4))
        #设置线程休眠时间防止被反爬虫

if __name__ == '__main__':
    key = '大数据'
    # 第一页URL格式和后面的网页不一样
    url = 'https://search.51job.com/list/000000,000000,0000,00,9,99,' + key + ',2,1.html?lang=c&stype=&postchannel=0000&workyear=99&cotype=99°reefrom=99&jobterm=99&companysize=99&providesalary=99&lonlat=0%2C0&radius=-1&ord_field=0&confirmdate=9&fromType=&dibiaoid=0&address=&line=&specialarea=00&from=&welfare='
    getUrl(url)
    # 后页[2,100)
    urls = [
        'https://search.51job.com/list/000000,000000,0000,00,9,99,' + key + ',2,{}.html?lang=c&stype=1&postchannel=0000&workyear=99&cotype=99°reefrom=99&jobterm=99&companysize=99&lonlat=0%2C0&radius=-1&ord_field=0&confirmdate=9&fromType=&dibiaoid=0&address=&line=&specialarea=00&from=&welfare='.format(
            i) for i in range(2, 100)]
    for url in urls:
        getUrl(url)

爬虫结果

爬虫结果我是以csv的格式存储的,看起来不太直观,所以我打算用wordcloud和直方图来可视化爬虫的结果。

python实现提取简历信息 python爬取简历数据_python实现提取简历信息

爬虫结果处理

一般来说,应聘者对一个工作的地点、工作名称、薪资和需要的技术最为关心,刚好上述爬虫的结果包含了这四个字段。

1、薪资结果的处理。在爬虫结果中,薪资在第二列,一般是诸如“1-2万/月”、“20万/年”和“500/天”的结果,先判断每个结果的最后一个字符是“年”、“月”和“天”的哪一个,确定处理的逻辑之后,再用re.sub函数将除了数字之外的字符替换为空格,最后对结果求均值就到了了每个结果的均值。

wordcloudPlotSalary.py

import re
import matplotlib.pyplot as plt
import csv
import numpy as np

data = []
with open("51job.csv",encoding='gbk') as csvfile:
    csv_reader = csv.reader(csvfile)  # 使用csv.reader读取csvfile中的文件
    data_header = next(csv_reader)  # 读取第一行每一列的标题
    for row in csv_reader:  # 将csv 文件中的数据保存到data中
        data.append(row)

data = np.array(data)  # 将list数组转化成array数组便于查看数据结构
header = np.array(data_header)
Jobinfo=data[:,10];
Salary=data[:,1];
name=data[:,0];
place=data[:,5];


word="".join(Salary);


font=r'C:\\Windows\\fonts\\msyh.ttf'#显示中文的关键步骤

# 去掉英文,保留中文
resultword=re.sub("[A-Za-z\[\`\~\!\@\#\$\^\&\*\(\)\=\|\{\}\'\:\;\'\,\[\]\<\>\?\~\。\@\#\\\&\*\%]", " ",word)
# 现在去掉了中文和标点符号
wl_space_split = resultword
salary_info=wl_space_split.split();
salary_list=[];

for s in salary_info:
    if(s[-1])=="年":
        ans=re.sub("[\u4e00-\u9fa5A-Za-z\/\-]", " ",s).split()
        sum=0;
        for i in ans:
            sum+=float(i)
        avg=sum/len(ans)/12
    elif (s[-1])=="月":
        ans = re.sub("[\u4e00-\u9fa5A-Za-z\/\-]", " ", s).split()
        sum=0;
        for i in ans:
            sum+=float(i)
        avg=sum/len(ans)
    elif (s[-1])=="天":
        ans = re.sub("[\u4e00-\u9fa5A-Za-z\/\-]", " ", s).split()
        sum=0;
        for i in ans:
            sum+=float(i)
        avg=sum/len(ans)*30
    salary_list.append(avg)

salary_array = np.array(salary_list)
salary_array[salary_array>6]=-0.00001 #剔除大于6的异常数据或者不合实际的数据
plt.rcParams['font.sans-serif']=['SimHei']
plt.hist(salary_array, bins =  [0,1,2,3,4,5,6])

plt.xlabel("工资区间(单位:万/月)") #设置X轴Y轴名称
plt.ylabel("数量")
plt.title("前程无忧大数据岗位工资(N="+str(len(salary_array))+",mean="+ str(round(salary_array.mean(),2))+ "万/月)")
plt.savefig('salaryHist.jpg')
plt.show();

python实现提取简历信息 python爬取简历数据_Python_02


2、需要的技术的处理。考虑到大数据要使用的技术绝大多数由外国人开发,如实我把大数据要使用的技术这一字段的中文全部替换为空格,然后用jieba提出掉一些无意义的助词,就得到了大数据要使用的技术的词云图。

wordcloudPlotJobinfo.py

import re
import jieba
from wordcloud import WordCloud,ImageColorGenerator,STOPWORDS
import  matplotlib.pyplot as plt
import csv
import numpy as np
'''
更多Python学习资料以及源码教程资料,可以在群1136201545免费获取
'''
data = []
with open("51job.csv",encoding='gbk') as csvfile:
    csv_reader = csv.reader(csvfile)  # 使用csv.reader读取csvfile中的文件
    data_header = next(csv_reader)  # 读取第一行每一列的标题
    for row in csv_reader:  # 将csv 文件中的数据保存到birth_data中
        data.append(row)



data = np.array(data)  # 将list数组转化成array数组便于查看数据结构
header = np.array(data_header)
Jobinfo=data[:,10];
Salary=data[:,1];
name=data[:,0];
place=data[:,5];

word="".join(Jobinfo);


font=r'C:\\Windows\\fonts\\msyh.ttf'#显示中文的关键步骤

# 去掉英文,保留中文
resultword=re.sub("[0-9\u4e00-\u9fa5\[\`\~\!\@\#\$\^\&\*\(\)\=\|\{\}\'\:\;\'\,\[\]\.\<\>\/\?\~\。\@\#\\\&\*\%\-]", "",word)
# 现在去掉了中文和标点符号
wordlist_after_jieba = jieba.cut(resultword)
wl_space_split = " ".join(wordlist_after_jieba)
print(wl_space_split);
# 设置停用词
sw = set(STOPWORDS)
sw.add(",")
sw.add(";")
sw.add("Responsibilities")
sw.add("experience")
sw.add("knowledge")
sw.add("communication")
sw.add("skill")
sw.add("office")
sw.add("support")
# 关键一步
my_wordcloud = WordCloud(font_path=font,scale=4,stopwords=sw,background_color='white',
                         max_words = 100,max_font_size = 60,random_state=20).generate(wl_space_split)

#显示生成的词云
plt.imshow(my_wordcloud)
plt.axis("off")
plt.show()

#保存生成的图片
my_wordcloud.to_file('Jobinfo.jpg')

python实现提取简历信息 python爬取简历数据_选择器_03


3、工作地点和职位名称的处理

wordcloudPlotPlace.py

import numpy as np
from PIL import Image
import re
import jieba
from wordcloud import WordCloud,ImageColorGenerator,STOPWORDS
# import wordcloud
import  matplotlib.pyplot as plt
import csv
import numpy as np
'''
更多Python学习资料以及源码教程资料,可以在群1136201545免费获取
'''
data = []
with open("51job.csv",encoding='gbk') as csvfile:
    csv_reader = csv.reader(csvfile)  # 使用csv.reader读取csvfile中的文件
    data_header = next(csv_reader)  # 读取第一行每一列的标题
    for row in csv_reader:  # 将csv 文件中的数据保存到birth_data中
        data.append(row)



data = np.array(data)  # 将list数组转化成array数组便于查看数据结构
header = np.array(data_header)
Jobinfo=data[:,10];
Salary=data[:,1];
name=data[:,0];
place=data[:,5];
# 打开存放项目名称的txt文件
# with open('content.txt','r',encoding='utf-8') as f:
#    word= (f.read())
#    f.close()
str="";
word=str.join(place);

# 图片模板和字体
# image=np.array(Image.open('ditu.jpg'))#显示中文的关键步骤
font=r'C:\\Windows\\fonts\\msyh.ttf'

# 去掉英文,保留中文
resultword=re.sub("[A-Za-z0-9\[\`\~\!\@\#\$\^\&\*\(\)\=\|\{\}\'\:\;\'\,\[\]\.\<\>\/\?\~\。\@\#\\\&\*\%\-]", "",word)
#resultword=re.sub("[A-Za-z0-9\[\`\~\!\@\#\$\^\&\*\(\)\=\|\{\}\'\:\;\'\,\[\]\.\<\>\/\?\~\。\@\#\\\&\*\%]", "",word)
# 现在去掉了中文和标点符号
wordlist_after_jieba = jieba.cut(resultword)
wl_space_split = " ".join(wordlist_after_jieba)
print(wl_space_split);
# 设置停用词
sw = set(STOPWORDS)
sw.add("研发")
sw.add("系列")
sw.add("区")

# 关键一步
my_wordcloud = WordCloud(font_path=font,scale=4,stopwords=sw,background_color='white',
                         max_words = 100,max_font_size = 60,random_state=20).generate(wl_space_split)
#my_wordcloud = WordCloud(background_color='white',
#                         width=800,height=600,margin=2).generate(wl_space_split)
#显示生成的词云
plt.imshow(my_wordcloud)
plt.axis("off")
plt.show()

#保存生成的图片
my_wordcloud.to_file('place.jpg')

python实现提取简历信息 python爬取简历数据_数组_04


职位名称词云:

wordcloudPlotName.py

import re
from wordcloud import WordCloud,ImageColorGenerator,STOPWORDS
import  matplotlib.pyplot as plt
import csv
import numpy as np
'''
更多Python学习资料以及源码教程资料,可以在群1136201545免费获取
'''
data = []
with open("51job.csv",encoding='gbk') as csvfile:
    csv_reader = csv.reader(csvfile)  # 使用csv.reader读取csvfile中的文件
    data_header = next(csv_reader)  # 读取第一行每一列的标题
    for row in csv_reader:  # 将csv 文件中的数据保存到birth_data中
        data.append(row)



data = np.array(data)  # 将list数组转化成array数组便于查看数据结构
header = np.array(data_header)
Jobinfo=data[:,10];
Salary=data[:,1];
name=data[:,0];
place=data[:,5];


word="".join(name);

# 图片模板和字体
#image=np.array(Image.open('model.jpg'))#显示中文的关键步骤
font=r'C:\\Windows\\fonts\\msyh.ttf'

# 去掉英文,保留中文
resultword=re.sub("[A-Za-z0-9\[\`\~\!\@\#\$\^\&\*\(\)\=\|\{\}\'\:\;\'\,\[\]\.\<\>\/\?\~\。\@\#\\\&\*\%\-]", " ",word)
#resultword=re.sub("[A-Za-z0-9\[\`\~\!\@\#\$\^\&\*\(\)\=\|\{\}\'\:\;\'\,\[\]\.\<\>\/\?\~\。\@\#\\\&\*\%]", "",word)
# 现在去掉了中文和标点符号
#wordlist_after_jieba = jieba.cut(resultword)
wl_space_split = resultword;
print(wl_space_split);
# 设置停用词
sw = set(STOPWORDS)
sw.add("广州")
sw.add("沈阳")
sw.add("武汉")
sw.add("双休")
sw.add("(周末双休)")
sw.add("五险一金")
sw.add("上海")
sw.add("杭州")
sw.add("急招")
sw.add("北京")
sw.add("周末双休")


# 关键一步
my_wordcloud = WordCloud(font_path=font,scale=4,stopwords=sw,background_color='white',
                         max_words = 100,max_font_size = 60,random_state=20).generate(wl_space_split)
#显示生成的词云
plt.imshow(my_wordcloud)
plt.axis("off")
plt.show()

#保存生成的图片
my_wordcloud.to_file('name.jpg')

python实现提取简历信息 python爬取简历数据_Python_05