利用正則爬取智聯

#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('<.*?>|&nbsp;'),'',info[0])
        rs_list[1] = re.sub(re.compile('<.*?>'),'',info[1])
        rs_list[-1] = re.sub(re.compile('<.*?>|&nbsp;'),'',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()
相關文章
相關標籤/搜索