python抓取boss直聘招聘信息

1.目前測試情況看只能抓取頭3頁,後續得重新換cookie抓取。
2.如果登錄自己boss賬戶,有可能導致賬戶臨時被封,測試情況是個人賬戶被封了一個小時。

#!/usr/bin/python
# -*- coding:utf-8 -*-

import requests
from bs4 import BeautifulSoup
import time
import xlrd
import xlwt
import random
import datetime

# 將日誌打印到下述文件
f = open("./test.log", 'w+')
# url:域名+地級市+區/縣級市,以 '/' 結尾,例:https://www.zhipin.com/c101210100/b_%E6%BB%A8%E6%B1%9F%E5%8C%BA/
# job:崗位,例 PHP
# cookie:登錄後的cookie,F12打開開發者模式,選擇Network,點擊Doc找到Request Headers下面的cookie,複製字符串
# path:Excel文檔保存的路徑,以 '/' 結尾
def spider4boss(url, job, cookie, path, page_start):
    # header頭信息 模擬火狐瀏覽器,加上自己的 cookie
    headers = {
        'user-agent': 'Mozilla/5.0',
        'cookie': cookie
    }
    # 打開Excel表 定義sheet 定義表頭
    workbook = xlwt.Workbook(encoding='utf-8')
    sheet = workbook.add_sheet('job_detail')
    head = ['職位名', '薪資', '公司名', '經驗', '學歷', '融資階段', '公司人數', '發佈時間', '實際經驗要求', '崗位網址', 'JD ']
    for h in range(len(head)):
        sheet.write(0, h, head[h])
    row = 1  # 第0行用來寫表頭
    # 判斷程序是否結束的標誌位
    is_end = 0

    for page in range(page_start, page_start+3):  # boss每個ip一次只能爬3頁
        # 一級url  c101210100:杭州市代號 b_%E6%BB%A8%E6%B1%9F%E5%8C%BA:濱江區轉碼
        main_url = url + "?query=" + job + "&page=" + str(page) + "&ka=page-" + str(page)
        print('第' + str(page) + '頁  ' + main_url)
        hud = ['職位名', '薪資', '公司名', '經驗', '學歷', '融資階段', '公司人數', '發佈時間', '實際經驗要求', '崗位網址', 'JD']
        print('\t'.join(hud))
        # 請求對象
        html = requests.get(main_url, headers=headers)
        # bs對象
        soup = BeautifulSoup(html.text, 'html.parser')
        #print(soup, file=f)
        # 標記 如果ip被反爬限制此行報錯,這一步需要進行滑塊驗證
        # 安裝Firefox後不再出現ip限制
        if soup.find('div', 'job-box') is None:
            print('又被限制ip了')
            return page_start
        # 判斷該頁是否已經無數據
        is_null = soup.find('div', 'job-box').find('div', 'job-list').find('ul')                    
                if len(is_null) == 1:  # 當前頁面爲空值爲1說明該頁無信息,退出循環
            # return 0  # 此處使用return返回不會進行Excel表保存,所以選擇用break結束循環
            # 標誌位,可以結束程序
            is_end = 1
            break
        for n in soup.find_all('div', 'job-primary'):
            res = []
            pass  # 不寫pass上面行會出warning,強迫症必須消除
            res.append(n.find('div', 'job-title').find('a').string)  # 添加職位名
            res.append(n.find('span', 'red').string)  # 添加薪資
            res.append(n.find('div', 'company-text').find('a').string)  # 添加公司名
            require = n.find('div', 'info-primary').find('p').contents
            res.append(require[0])  # 添加地區
            res.append(require[2])  # 添加經驗
            #res.append(require[4])  # 添加學歷
            info = n.find('div', 'company-text').find('p').contents
            #res.append(info[0])  # 行業
            if 4 > len(info) > 2 and info[2].index('人') != 0:
                res.append('無信息')  # 融資
                res.append(info[2])  # 規模
            else:
                res.append(info[2])  # 融資
                res.append(info[4])  # 規模
            hr = n.find('div', 'info-publis').find('h3', 'name').contents
            #res.append(hr[3] + '--' + hr[1])  # 發佈者
            res.append(n.find('div', 'job-title').find('span','job-pub-time').string)
            #if n.find('div', 'info-publis').find('p').string[3:] == '昨天':  # 如果發佈時間是 "昨天",格式化爲日期
            #    res.append(str(datetime.date.today()-datetime.timedelta(days=1))[5:])  # 發佈時間
            #elif n.find('div', 'info-publis').find('p').string[5:6] == ':':
            #    res.append(str(datetime.date.today())[5:])  # 發佈時間
            #else:  # 格式化日期
            #    res.append(n.find('div', 'info-publis').find('p').string[3:].replace('月', '-').replace('日', ''))
            job_detail = n.find('div', 'job-title').find('span', 'job-name').find('a')
            job_url = 'https://www.zhipin.com/' + job_detail['href']  # 崗位詳情url
            # 提取真正的工作經驗要求
            html2 = requests.get(job_url, headers=headers)
            soup2 = BeautifulSoup(html2.text, 'html.parser')
            # 標記 如果ip被反爬限制此行報錯,下一步需要進行滑塊驗證
            # 安裝Firefox後不再出現ip限制
            if soup2.find('div', 'job-sec') is None:
                print('又被限制ip了')
                return page_start
            job_sec = soup2.find('div', 'job-sec').find('div', 'text').contents
            exp = 0  # 初始爲0 取到一個工作經驗要求後置1
            # 將JD保存
            job_description = []
            for i in range(len(job_sec)):
                if i % 2 == 0:  # job_sec中還存了html標籤 <br> 不是字符串,用find方法返回None,需要去除
                    job_description.append(job_sec[i])
                    # 確定位置                                                                                 
                    pot = job_sec[i].find('年')
                    if pot != -1 and exp == 0:
                        pot2 = job_sec[i].find('年以上')
                        if pot2 != -1:
                            # 再做一次判斷,有的公司在數字後敲了空格
                            if job_sec[i][pot - 1:pot] == ' ':
                                res.append(job_sec[i][pot - 2:pot + 3])
                            else:
                                res.append(job_sec[i][pot - 1:pot + 3])
                        else:
                            if job_sec[i][pot - 1:pot] == ' ':
                                res.append(job_sec[i][pot - 2:pot + 1])
                            else:
                                res.append(job_sec[i][pot - 1:pot + 1])
                        # 只輸出一個時間要求 不重複輸出,需要用戶手動檢查崗位描述中的要求
                        exp = 1
            # 如果崗位描述中沒有經驗要求,填空字符
            if exp == 0:
                res.append('')
            res.append(job_url)  # 崗位描述鏈接
            job_description = ' '.join(job_description)[33:-29]
            res.append(job_description)  # 崗位描述
            # 寫入Excel
            for i in range(len(res)):
                sheet.write(row, i, res[i])
            row += 1
            #print(res)
            # quit()
            time.sleep(random.randint(100, 500)/1000)
    workbook.save(path + str(datetime.date.today())[5:] + '_' + str(int(page_start/3+1)) + '_boss_job.xls')  # 保存Excel
    print('寫入excel成功')
    if 0 == is_end:
        return 200
    else:
        return 0


def verify_slider():
    from selenium import webdriver
    from selenium.webdriver import ActionChains
    browser = webdriver.Firefox()
    browser.implicitly_wait(5)
    browser.get('https://www.zhipin.com/verify/slider')
    browser.execute_script("Object.defineProperties(navigator,{webdriver:{get:() => false}});")
    element = browser.find_element_by_id('nc_1_n1z')
    action = ActionChains(browser)
    action.drag_and_drop_by_offset(element, 280, 0).perform()
    time.sleep(5)
    browser.close()    

def rec_spider(page=1):
    res = spider4boss(url, job, cookie, path, page)
    if 200 == res:
        page += 3
        rec_spider(page)
    elif 200 > res > 0:
        print('在第 ' + str(res) + ' 頁需要進行人機驗證')
        # 調用驗證方法進行驗證
        verify_slider()
        # 繼續爬取
        rec_spider(res)
    else:  # 爬取完成
        print('爬取完成')
        quit()


def merge_excel(date):
    pass


if __name__ == "__main__":
    cookie = 'Hm_lpvt_194df3105ad7148dcf2b98a91b5e727a=1585822170; Hm_lvt_194df3105ad7148dcf2b98a91b5e727a=1585819697,1585822166; __a=27860491.1585819695..1585819695.6.1.6.2; __l=l=%2Fwww.zhipin.com%2Fweb%2Fgeek%2Fchat%3Fka%3Dheader-message&r=&friend_source=0&g=%2Fwww.zhipin.com%2Fbeijing%2F%3Fsid%3Dsem_pz_bdpc_dasou_title&friend_source=0; __zp_stoken__=b67aky0C7VtMD%2Fpa0jX2j%2FVQSUxVDSdHyYt%2BCMenwdUjlJFNoctlW21JHqhbxHLLCbg2cSgMj7gGe7oIZpRAU6Ghs8YsUgf8chDqcQ8DgAI7KbhiNugjm0yxNosIk1aX15g7; __g=sem_pz_bdpc_dasou_title; __zp_seo_uuid__=ed543f89-cf6c-4764-882f-f8cf15281dbf; lastCity=101010100; sid=sem_pz_bdpc_dasou_title; _uab_collina=158581969696974364880318; __c=1585819695; _bl_uid=81kFe8Iqi0sk8a3Lsov96t3r67pL'
    #url = 'https://www.zhipin.com/c101210100/b_%E6%BB%A8%E6%B1%9F%E5%8C%BA/'
    url = 'https://www.zhipin.com/c101010100/'
    job = 'go'
    path = './'
    # spider4boss(url, job, cookie, path, 1)
    # verify_slider()
    rec_spider()                                                                                          

參考:
Python爬取Boss直聘上面的招聘信息

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章