1.1 前提數(shù)據(jù)這里需要知道頁面的 id 才能生成詳細(xì)的鏈接,,在 文章《Python爬蟲框架Scrapy實(shí)戰(zhàn) - 抓取BOSS直聘招聘信息》 (鏈接:http://www./blog/scrapy_zhipin_spider.html)中,,我們已經(jīng)拿到招聘信息的大部分信息,,里面有個 pid 字段就是用來唯一區(qū)分某條招聘,,并用來拼湊詳細(xì)鏈接的。 是吧,,明眼人一眼就看出來了,。 1.2 詳情頁分析
詳情頁如下圖所示
在詳情頁中,比較重要的就是職位描述 和工作地址 這兩個 由于在頁面代碼中崗位職責(zé) 和任職要求 是在一個 div 中的,,所以在抓的時候就不太好分,,后續(xù)需要把這個連體嬰兒,分開分析,。 1.3 爬蟲用到的庫
requests BeautifulSoup4 pymongo
對應(yīng)的安裝文檔依次如下,,就不細(xì)說了 安裝 Requests - Requests 2.18.1 文檔(http://docs./zh_CN/latest/user/install.html) 安裝 Beautiful Soup - Beautiful Soup 4.2.0 文檔(https://www./software/BeautifulSoup/bs4/doc/index.zh.html#id5) PyMongo安裝使用筆記(http://www.jb51.net/article/64996.htm)
1.4 Python 代碼''' @author: jtahstu @contact: root@ @site: http://www. @time: 2017/12/10 00:25 ''' # -*- coding: utf-8 -*- import requests from bs4 import BeautifulSoup import time from pymongo import MongoClient
headers = { 'x-devtools-emulate-network-conditions-client-id': '5f2fc4da-c727-43c0-aad4-37fce8e3ff39', 'upgrade-insecure-requests': '1', 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36', 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', 'dnt': '1', 'accept-encoding': 'gzip, deflate', 'accept-language': 'zh-CN,zh;q=0.8,en;q=0.6', 'cookie': '__c=1501326829; lastCity=101020100; __g=-; __l=r=https%3A%2F%2Fwww.google.com.hk%2F&l=%2F; __a=38940428.1501326829..1501326829.20.1.20.20; Hm_lvt_194df3105ad7148dcf2b98a91b5e727a=1501326839; Hm_lpvt_194df3105ad7148dcf2b98a91b5e727a=1502948718; __c=1501326829; lastCity=101020100; __g=-; Hm_lvt_194df3105ad7148dcf2b98a91b5e727a=1501326839; Hm_lpvt_194df3105ad7148dcf2b98a91b5e727a=1502954829; __l=r=https%3A%2F%2Fwww.google.com.hk%2F&l=%2F; __a=38940428.1501326829..1501326829.21.1.21.21', 'cache-control': 'no-cache', 'postman-token': '76554687-c4df-0c17-7cc0-5bf3845c9831' } conn = MongoClient('127.0.0.1', 27017) db = conn.iApp # 連接mydb數(shù)據(jù)庫,,沒有則自動創(chuàng)建
def init(): items = db.jobs_php.find().sort('pid') for item in items: if 'detail' in item.keys(): # 在爬蟲掛掉再此爬取時,跳過已爬取的行 continue detail_url = 'https://www.zhipin.com/job_detail/%s.html?ka=search_list_1' % item['pid'] print(detail_url) html = requests.get(detail_url, headers=headers) if html.status_code != 200: # 爬的太快網(wǎng)站返回403,,這時等待解封吧 print('status_code is %d' % html.status_code) break soup = BeautifulSoup(html.text, 'html.parser') job = soup.select('.job-sec .text') if len(job) <>1: continue item['detail'] = job[0].text.strip() # 職位描述 location = soup.select('.job-sec .job-location') item['location'] = location[0].text.strip() # 工作地點(diǎn) item['updated_at'] = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) # 實(shí)時爬取時間 res = save(item) # 保存數(shù)據(jù) print(res) time.sleep(40) # 停停停
# 保存數(shù)據(jù)到 MongoDB 中 def save(item): return db.jobs_php.update_one({'_id': item['_id']}, {'$set': item})
if __name__ == '__main__': init()
代碼 easy,,初學(xué)者都能看懂。 1.5 再啰嗦幾句
在文章《Python爬蟲框架Scrapy實(shí)戰(zhàn) - 抓取BOSS直聘招聘信息》 (鏈接:http://www./blog/scrapy_zhipin_spider.html)中,,只是爬了 上海-PHP 近300條數(shù)據(jù),,后續(xù)改了代碼,把12個城市的 PHP 相關(guān)崗位的數(shù)據(jù)都抓下來了,,有3500+條數(shù)據(jù),,慢慢爬吧,急不來,。 像這樣
二,、數(shù)據(jù)清洗
2.1 校正發(fā)布日期'time' : '發(fā)布于03月31日', 'time' : '發(fā)布于昨天', 'time' : '發(fā)布于11:31',
這里拿到的都是這種格式的,所以簡單處理下 import datetime from pymongo import MongoClient db = MongoClient('127.0.0.1', 27017).iApp def update(data): return db.jobs_php.update_one({'_id': data['_id']}, {'$set': data}) # 把時間校正過來 def clear_time(): items = db.jobs_php.find({}) for item in items: if not item['time'].find('布于'): continue item['time'] = item['time'].replace('發(fā)布于', '2017-') item['time'] = item['time'].replace('月', '-') item['time'] = item['time'].replace('日', '') if item['time'].find('昨天') > 0: item['time'] = str(datetime.date.today() - datetime.timedelta(days=1)) elif item['time'].find(':') > 0: item['time'] = str(datetime.date.today()) update(item) print('ok')
2.2 校正薪水以數(shù)字保存'salary' : '5K-12K',
#處理成下面的格式 'salary' : { 'low' : 5000, 'high' : 12000, 'avg' : 8500.0 },
# 薪水處理成數(shù)字 def clear_salary(): items = db.jobs_php.find({}) for item in items: if type(item['salary']) == type({}): continue salary_list = item['salary'].replace('K', '000').split('-') salary_list = [int(x) for x in salary_list] item['salary'] = { 'low': salary_list[0], 'high': salary_list[1], 'avg': (salary_list[0] + salary_list[1]) / 2 } update(item) print('ok')
2.3 根據(jù) 工作經(jīng)驗?zāi)晗?劃分招聘等級# 設(shè)置招聘的水平 def set_level(): items = db.jobs_php.find({}) for item in items: if item['workYear'] == '應(yīng)屆生': item['level'] = 1 elif item['workYear'] == '1年以內(nèi)': item['level'] = 2 elif item['workYear'] == '1-3年': item['level'] = 3 elif item['workYear'] == '3-5年': item['level'] = 4 elif item['workYear'] == '5-10年': item['level'] = 5 elif item['workYear'] == '10年以上': item['level'] = 6 elif item['workYear'] == '經(jīng)驗不限': item['level'] = 10 update(item) print('ok')
這里有點(diǎn)坑的就是,,一般要求經(jīng)驗不限 的崗位,,需求基本都寫在任職要求 里了,所以為了統(tǒng)計的準(zhǔn)確性,,這個等級的數(shù)據(jù),,后面會被舍棄掉。 2017-12-14 更新: 從后續(xù)的平均數(shù)據(jù)來看,,這里的經(jīng)驗不限 ,,一般要求的是1-3年 左右,但是還是建議舍棄掉,。
2.4 區(qū)分開<崗位職責(zé)>和<任職要求>
對于作者這個初學(xué)者來說,,這里還沒有什么好的方法,知道的同學(xué),,請務(wù)必聯(lián)系作者,,聯(lián)系方式在個人博客里 so , i'm sorry. 為什么這兩個不好劃分出來呢? 因為這里填的并不統(tǒng)一,,可以說各種花樣,,有的要求在前,職責(zé)在后,,有的又換個名字區(qū)分,。目前看到的關(guān)于要求的有['任職條件', '技術(shù)要求', '任職要求', '任職資格', '崗位要求'] 這么多說法。然后順序還不一樣,,有的要求在前,,職責(zé)在后,有的又反之,。 舉個栗子 會基本的php編程,!能夠修改簡單的軟件,!對云服務(wù)器和數(shù)據(jù)庫能夠運(yùn)用!懂得微信公眾賬號對接和開放平臺對接,!我們不是軟件公司,,是運(yùn)營公司!想找好的公司學(xué)習(xí)的陜西基本沒有,,要到沿海城市去,!但是我們是實(shí)用型公司,主要是軟件應(yīng)用和更適合大眾,! 啥也不說的,,這里可以認(rèn)為這是一條臟數(shù)據(jù) 了。 不行,,再舉個栗子 PHP中級研發(fā)工程師(ERP/MES方向) 1,、計算機(jī)或相關(guān)學(xué)科本科或本科以上學(xué)歷; 2,、php和Java script的開發(fā)經(jīng)驗,。 3、Linux和MySQL數(shù)據(jù)庫的開發(fā)經(jīng)驗,; 5,、有ERP、MES相關(guān)開發(fā)經(jīng)驗優(yōu)先,; 6,、英語的讀寫能力; 7,、文化的開放性,; 我們提供 1、有趣的工作任務(wù),; 2,、多元的工作領(lǐng)域; 3,、與能力相關(guān)的收入,; 4、年輕,、開放并具有創(chuàng)造力的團(tuán)隊和工作氛圍,; 5、不斷接觸最新科技(尤其是工業(yè)4.0相關(guān)),; 6、可適應(yīng)短期出差(提供差補(bǔ)),; 這個只有要求,,沒職責(zé),,還多了個提供,我樂個趣 ╮(╯▽╰)╭ 所以,,氣的想罵人,。 ok ,現(xiàn)在我們的數(shù)據(jù)基本成這樣了 { '_id' : ObjectId('5a30ad2068504386f47d9a4b'), 'city' : '蘇州', 'companyShortName' : '藍(lán)海彤翔', 'companySize' : '100-499人', 'education' : '本科', 'financeStage' : 'B輪', 'industryField' : '互聯(lián)網(wǎng)', 'level' : 3, 'pid' : '11889834', 'positionLables' : [ 'PHP', 'ThinkPHP' ], 'positionName' : 'php研發(fā)工程師', 'salary' : { 'avg' : 7500.0, 'low' : 7000, 'high' : 8000 }, 'time' : '2017-06-06', 'updated_at' : '2017-12-13 18:31:15', 'workYear' : '1-3年', 'detail' : '1,、處理landcloud云計算相關(guān)系統(tǒng)的各類開發(fā)和調(diào)研工作,;2、處理coms高性能計算的各類開發(fā)和調(diào)研工作崗位要求:1,、本科學(xué)歷,,兩年以上工作經(jīng)驗,熟悉PHP開發(fā),,了解常用的php開發(fā)技巧和框架,;2、了解C++,,python及Java開發(fā),;3、有一定的研發(fā)能力和鉆研精神,;4,、有主動溝通能力和吃苦耐勞的精神。', 'location' : '蘇州市高新區(qū)科技城錦峰路158號101park8幢' }
由于還沒到數(shù)據(jù)展示的時候,,所以現(xiàn)在能想到的就是先這樣處理了,。 項目開源地址:http://git./jtahstu/Scrapy_zhipin 三、展望和設(shè)想 首先這個小玩意數(shù)據(jù)量并不夠多,,因為爬取時間短,,站點(diǎn)唯一,再者廣度局限在 PHP 這一個崗位上,,以致存在一定的誤差,。 所以為了數(shù)據(jù)的豐富和多樣性,這個爬蟲是一定要持續(xù)跑著的,,至少要抓幾個月的數(shù)據(jù) 才算可靠吧,。 然后準(zhǔn)備再去抓下拉勾網(wǎng) 的招聘數(shù)據(jù),這也是個相對優(yōu)秀的專業(yè) IT 招聘網(wǎng)站了,,數(shù)據(jù)也相當(dāng)多,,想當(dāng)初找實(shí)習(xí)找正式工作,都是在這兩個 APP 上找的,,其他的網(wǎng)站幾乎都沒看,。 最后,對于科班出身的學(xué)弟學(xué)妹們,,過來人說一句,,編程相關(guān)的職業(yè)就不要去志連,、錢塵烏有、five eight桐城了,,好嗎,?那里面都發(fā)的啥呀,看那些介紹心里沒點(diǎn)數(shù)嗎,? 四,、help 這里完全就是作者本人依據(jù)個人微薄的見識,主觀臆斷做的一些事情,,所以大家有什么點(diǎn)子和建議,,都可以聯(lián)系作者,多交流交流嘛,。 后續(xù)會公開所有數(shù)據(jù),,大家自己可以弄著玩玩吧。 我們太年輕,,以致都不知道以后的時光,,竟然那么長,長得足夠讓我們把一門技術(shù)研究到頂峰,,亂花漸欲迷人眼,,請不要忘了根本好嗎。 生活總是讓我們遍體鱗傷,,但到后來,,那些受傷的地方一定會變成我們最強(qiáng)壯的地方。 —海明威 《永別了武器》
|