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()