#coding:utf-8 import re from urllib import request,parse # xlwt 操做excel表格 import xlwt from random import choice # 1.建立一个工做簿对象 # workbook = xlwt.Workbook(encoding='utf-8') # # 2.添加一张表 # sheet = workbook.add_sheet('python职位表') # # 3.向表中添加数据 # sheet.write(0,0,'职位名称') # sheet.write(0,1,'工做地点') # sheet.write(0,2,'公司名称') # sheet.write(0,3,'薪资待遇') # sheet.write(0,4,'发布日期') # # 4.保存 # workbook.save('python职位信息.xls') ''' https://sou.zhaopin.com/jobs/searchresult.ashx?kw=python&sm=0&p=1 https://sou.zhaopin.com/jobs/searchresult.ashx?jl=北京%2B上海%2B广州%2B深圳%2B杭州&kw=python&p=1 jl 工做地点 kw 搜索关键字 p 页码 ''' ''' 1.初始化函数 kw搜索关键词,基础的url地址,请求头,用来记录html源代码属性,total_page总页码 2.start函数 爬虫的启动函数 3.get_html函数 根据url地址,获取html源代码,转换为str类型,并赋值给self.html 4.parse_total函数 从html源代码中,根据正则提取职位总个数,计算总页码,math.ceil()向上取整 5.parse_info函数 根据总页码,获取每一页的html源代码,根据正则提取职位信息,并对数据进行简单的清洗工做 将数据存储表格中 6.filter函数 将正则匹配到的数据进行清洗,把多余的数据剔除 ''' # 智联招聘爬虫类 class ZLSpider(object): def __init__(self,kw,citys): data = { 'jl':'+'.join(citys), 'kw':kw, } # 记录搜索关键词 self.kw = kw # 编码参数 data = parse.urlencode(data) # 拼接完整地址 self.url = 'https://sou.zhaopin.com/jobs/searchresult.ashx?'+data # 请求头列表 self.UserAgents = [ 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0', 'Mozilla/5.0 (Windows NT 10; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0', 'Mozilla/5.0 (Windows; U; Windows NT 5.2) AppleWebKit/525.13 (KHTML, like Gecko) Version/3.1 Safari/525.13' ] # 声明html属性 记录html源代码 self.html = '' # 将数据中的特殊字符剔除 def fillter_data(self,info): # 元组转换为列表 rs_list = list(info) rs_list[0] = re.sub(re.compile('<.*?>| '),'',info[0]) rs_list[1] = re.sub(re.compile('<.*?>'),'',info[1]) rs_list[-1] = re.sub(re.compile('<.*?>| '),'',info[-1]) return rs_list # 发送请求的函数 def get_html(self,url): # 建立请求对象,随机取出请求头 # parse.urlencode 对url进行编码 req = request.Request(url,headers={ 'User-Agent':choice( self.UserAgents)}) # 发起请求,接收响应 response = request.urlopen(req) # 转换html utf-8 gbk gb2312 self.html = response.read().decode('utf-8') # 解析职位总个数,计算总页数 def parse_total(self): print(self.url) # 准备正则 pattern = re.compile('<span.*?em>(.*?)</em>',re.S) # search() rs = re.search(pattern,self.html) # 总职位数 转换整数 total_zw = int(rs.group(1)) # 计算总页数 import math # ceil()向上取整 # total_zw//60 向下取整 total_page = math.ceil(total_zw/60) print('共有{}个职位信息,共{}页'.format(total_zw,total_page)) # 智联招聘网页只显示前90页数据 self.total_page = 90 # 解析每一页的职位信息 def parse_info(self): workbook = xlwt.Workbook(encoding='utf-8') sheet = workbook.add_sheet(self.kw+'职位表') sheet.write(0,0,'职位名称') sheet.write(0,1,'公司名称') sheet.write(0,2,'最低月薪') sheet.write(0,3,'最高月薪') sheet.write(0,4,'工做地点') sheet.write(0,5,'发布日期') # 向表格中写入数据时的行号 count = 1 for page in range(1,11): print('正在爬取第{}页,请稍后...'.format(page)) # 拼接带页码的url地址 url = self.url+'&p={}'.format(page) self.get_html(url) # 准备正则 pattern = re.compile('<table.*?class="newlist.*?<td class="zwmc.*?<a.*?>(.*?)</a>.*?class="gsmc.*?<a.*?>(.*?)</a>.*?class="zwyx.*?>(.*?)</td>.*?class="gzdd.*?>(.*?)</td.*?class="gxsj.*?>(.*?)</td>',re.S) res = re.findall(pattern,self.html) for s in res: rs_list = self.fillter_data(s) sheet.write(count,0,rs_list[0]) sheet.write(count,1,rs_list[1]) # 把职位月薪分红最低和最高 if '-' in rs_list[2]: max_money = rs_list[2].split('-')[1] min_money = rs_list[2].split('-')[0] else: max_money = min_money = '面议' sheet.write(count,2,min_money) sheet.write(count,3,max_money) sheet.write(count,4,rs_list[3]) sheet.write(count,5,rs_list[4]) # count+1 count += 1 workbook.save(self.kw+'智联职位信息.xls') # 启动爬虫函数 def start(self): self.get_html(self.url) self.parse_total() self.parse_info() if __name__ == '__main__': kw = input('请输入要查询的职位名称:') citys = [] while len(citys) <5: city = input('请输入查询的城市,最多5个(q结束):') if city == 'q': break citys.append(city) zl = ZLSpider(kw,citys) zl.start()