2018年8月30日 星期四

都說​ Python ​趕超 Java,爬取拉勾網資料發現它的薪資已高至 50K!| 技術頭條




文章摘要: 人工智慧的快速發展以及大資料時代的來臨,使得 Python 語言不僅在人工智慧領域大放異彩,在數據處理上也有著得天獨厚的優勢,在 Web 開發、網路程式設計、自動化運維、遊戲開發、金融等領域扮演著越來越重要的角色。



作者 | lowelong


責編 | 郭芮


人工智慧的快速發展以及大資料時代的來臨,使得 Python 語言不僅在人工智慧領域大放異彩,在數據處理上也有著得天獨厚的優勢,在 Web 開發、網路程式設計、自動化運維、遊戲開發、金融等領域扮演著越來越重要的角色。


百度搜索指數表明,2017 年 7 月份開始,Python 的搜尋指數已經超過了 Java。Python 語言的熱門由此可見一斑。




本文中,筆者決定在拉勾網(一家為網際網路從業者提供工作機會的招聘網站)上爬取相關 Python 職位資訊,對職位資料(薪酬、學歷要求、區域資訊、工作經驗等)進行圖形視覺化分析。


前期準備


1、網頁分析


開啟拉勾網網站搜尋 Python,可以發現每頁有 15 條職位資訊資料,最多有 30 頁資料可以檢視,共 450 條職位資訊。我們需要獲取的資訊包括:職位、公司名稱、薪酬範圍、所在區域、學歷要求、工作經驗、公司融資情況、公司人數、工作要求描述。



2、請求資料分析


通過 Chrome 瀏覽器訪問拉勾網,開啟 Console 控制檯可以發現,當進行翻頁的時候,是通過 xhr 的請求方式請求的。通過觀察,我們可以發現,URL 裏面的 city 代表的是城市,post 引數 kd 代表的是搜尋的職位,pn 是 page number,表示頁碼。



3、職位列表JSON返回資料的分析獲取



通過 JSON 庫進行資料的解析,獲取相關資訊。需要注意的是,我們需要記得保留 positionID,用於下一步獲取工作描述資訊。


def get_lagou(page,city,kd):
url = "https://www.lagou.com/jobs/positionAjax.json"
querystring = "px": "new", "city": city, "needAddtionalResult": "false", "isSchoolJob": "0"
payload = "first=false&pn=" + str(page) + "&kd="+str(kd)
cookie = "JSESSIONID=" + get_uuid + ";"
"user_trace_token=" + get_uuid + "; LGUID=" + get_uuid + "; index_location_city=%E6%88%90%E9%83%BD; "
"SEARCH_ID=" + get_uuid + "; _gid=GA1.2.717841549.1514043316; "
"_ga=GA1.2.952298646.1514043316; "
"LGSID=" + get_uuid + "; "
"LGRID=" + get_uuid + "; "
headers = "cookie": cookie,"origin": "https://www.lagou.com","x-anit-forge-code": "0","accept-encoding": "gzip, deflate, br","accept-language": "zh-CN,zh;q=0.8,en;q=0.6","user-agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36","content-type": "application/x-www-form-urlencoded; charset=UTF-8","accept": "application/json, text/javascript, */*; q=0.01","referer": "https://www.lagou.com/jobs/list_Java?px=new&city=%E6%88%90%E9%83%BD","x-requested-with": "XMLHttpRequest","connection": "keep-alive","x-anit-forge-token": "None","cache-control": "no-cache","postman-token": "91beb456-8dd9-0390-a3a5-64ff3936fa63"
response = requests.request("POST", url, data=payload.encode("utf-8"), headers=headers, params=querystring)
# print(response.text)
hjson = json.loads(response.text)
for i in range(15):
positionName=hjson["content"]["positionResult"]["result"][i]["positionName"]
companyId = hjson["content"]["positionResult"]["result"][i]["companyId"]
positionId= hjson["content"]["positionResult"]["result"][i]["positionId"]
salary = hjson["content"]["positionResult"]["result"][i]["salary"]
city= hjson["content"]["positionResult"]["result"][i]["city"]
district= hjson["content"]["positionResult"]["result"][i]["district"]
companyShortName= hjson["content"]["positionResult"]["result"][i]["companyShortName"]
education= hjson["content"]["positionResult"]["result"][i]["education"]
workYear= hjson["content"]["positionResult"]["result"][i]["workYear"]
industryField= hjson["content"]["positionResult"]["result"][i]["industryField"]
financeStage= hjson["content"]["positionResult"]["result"][i]["financeStage"]
companySize= hjson["content"]["positionResult"]["result"][i]["companySize"]
job_desc = get_job_desc(positionId)
positionName_list.append(positionName)
salary_list.append(salary)
city_list.append(city)
district_list.append(district)
companyShortName_list.append(companyShortName)
education_list.append(education)
workYear_list.append(workYear)
industryField_list.append(industryField)
financeStage_list.append(financeStage)
companySize_list.append(companySize)
#job_desc_list.append(job_desc)

4、獲取工作資訊描述



通過觀察發現,開啟具體職位的詳細頁面時,URL 裏面的數值(例如下圖的 URL 裏面的 4789029)就是職位的 positionID,該 positionID 可以通過上一步的職位列表 JSON 返回資料獲取。



通過 requests 請求頁面資訊,再通過 xpath 獲取工作描述資訊。


def get_job_desc(id):
url = "https://www.lagou.com/jobs/"+str(id)+".html"
cookie = "JSESSIONID=" + get_uuid + ";"
"user_trace_token=" + get_uuid + "; LGUID=" + get_uuid + "; index_location_city=%E6%88%90%E9%83%BD; "
"SEARCH_ID=" + get_uuid + "; _gid=GA1.2.717841549.1514043316; "
"_ga=GA1.2.952298646.1514043316; "
"LGSID=" + get_uuid + "; "
"LGRID=" + get_uuid + "; "
headers = "cookie": cookie,"origin": "https://www.lagou.com","x-anit-forge-code": "0","accept-encoding": "gzip, deflate, br","accept-language": "zh-CN,zh;q=0.8,en;q=0.6","user-agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36","content-type": "application/x-www-form-urlencoded; charset=UTF-8","accept": "application/json, text/javascript, */*; q=0.01","referer": "https://www.lagou.com/jobs/list_Java?px=new&city=%E6%88%90%E9%83%BD","x-requested-with": "XMLHttpRequest","connection": "keep-alive","x-anit-forge-token": "None","cache-control": "no-cache","postman-token": "91beb456-8dd9-0390-a3a5-64ff3936fa63"
response = requests.request("GET", url, headers=headers)
x = etree.HTML(response.text)
data = x.xpath("//*[@id="job_detail"]/dd[2]/div/*/text")
return "".join(data)


資料獲取 —— 爬蟲


1、設定 cookies 和 headers


如果不設定相關資訊,會不允許爬取,返回提示:「您操作太頻繁,請稍後再訪問」。所以,我們需要設定 headers 和 cookies 資訊。


def get_lagou(page,city,kd):
url = "https://www.lagou.com/jobs/positionAjax.json"
querystring = "px": "new", "city": city, "needAddtionalResult": "false", "isSchoolJob": "0"
payload = "first=false&pn=" + str(page) + "&kd="+str(kd)
cookie = "JSESSIONID=" + get_uuid + ";"
"user_trace_token=" + get_uuid + "; LGUID=" + get_uuid + "; index_location_city=%E6%88%90%E9%83%BD; "
"SEARCH_ID=" + get_uuid + "; _gid=GA1.2.717841549.1514043316; "
"_ga=GA1.2.952298646.1514043316; "
"LGSID=" + get_uuid + "; "
"LGRID=" + get_uuid + "; "
headers = "cookie": cookie,"origin": "https://www.lagou.com","x-anit-forge-code": "0","accept-encoding": "gzip, deflate, br","accept-language": "zh-CN,zh;q=0.8,en;q=0.6","user-agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36","content-type": "application/x-www-form-urlencoded; charset=UTF-8","accept": "application/json, text/javascript, */*; q=0.01","referer": "https://www.lagou.com/jobs/list_Java?px=new&city=%E6%88%90%E9%83%BD","x-requested-with": "XMLHttpRequest","connection": "keep-alive","x-anit-forge-token": "None","cache-control": "no-cache","postman-token": "91beb456-8dd9-0390-a3a5-64ff3936fa63"

2、延時設定和分頁爬取



避免爬取速度過快被封,設定延時時間為 3-5 秒。通過 for 迴圈進行分頁資料的爬取。


def main(pages,city,job):
for n in range(1, pages+1):
get_lagou(n,city,job)
time.sleep(round(random.uniform(3, 5), 2))
write_to_csv(city,job)

資料儲存與處理


1、CSV 資料儲存


由於資料量不大,最多 450 條資料,採用 CSV 的儲存方式。


2、數據處理


後續統計月薪的佔比,由於薪酬範圍是可以自定義範圍,沒有一個統一的標準。例如薪酬可以是 10k-20k、5k-8k、11k-18k、10k-16k 等情況,後續不利於薪酬範圍的視覺化,所以將薪酬歸納分類到這幾種:2k 以下、2k-5k、5k-10k、10k-15k、15k-25k、25k-50k、50k 以上。


假如薪酬為 10k-20k, 則認為在 10k-15k、15k-25k 這兩種歸類裏面都包含。採用正規表示式進行歸類彙總:


def salary_categorize(salarys):
dict = "2k以下": 0, "2k-5k": 0, "5k-10k": 0,"10k-15k":0,"15k-25k":0,"25k-50k":0,"50k以上":0
for salary in salarys:
if re.match("^[0-1]k-*|.*-[0-1]k$",salary)!=None:
dict["2k以下"] += 1
if re.match("^[2-4]k-*|.*-[2-4]k$",salary)!=None:
dict["2k-5k"] += 1
if re.match("^[5-9]k-*|.*-[5-9]k$", salary)!=None:
dict["5k-10k"] += 1
if re.match("^1[0-4]k-*|.*-1[0-4]k$", salary)!=None:
dict["10k-15k"] += 1
if re.match("^1[5-9]k-*|^2[0-4]k-*|.*-1[5-9]k$|.*-2[0-4]k$", salary)!=None:
dict["15k-25k"] += 1
if re.match("^2[5-9]k-*|^[3-4][0-9]k-*|.*-2[5-9]k$|.*-[3-4][0-9]k$", salary)!=None:
dict["25k-50k"] += 1
if re.match("^[5-9][0-9]k-*|.*-[5-9][0-9]k$|^d3,k-*|.*-d3,k$", salary)!=None:
dict["50k以上"] += 1
return dict

公司所屬行業可以是多個,一般以逗號分隔,但存在部分是以頓號和空格分隔的情況,還有可能存在沒有寫明相關行業的情況。對此,通過 Python 的 re 庫可以處理多個分隔符分隔的資料,所屬行業為空,則跳過。



def industryField_counts(csv_file):
industryFields =
d = pd.read_csv(csv_file, engine="python", encoding="utf-8")
info = d["industryField"]
for i in range(len(info)):
try:
data = re.split("",info[i])
except:
continue
for j in range(len(data)):
industryFields.append(data[j])
counts = Counter(industryFields)
return counts

資料視覺化與解讀


1、公司相關情況分析





從行業情況和公司規模來看,移動網際網路佔有 40% 的需求,資料服務+大資料+人工智慧佔了 10% 的比例。Python 非常強大,適合的領域包括 Web 開發、網路程式設計、爬蟲、雲端計算、人工智慧、自動化運維等,所以不管公司規模是大還是小,融資情況如何,都普遍需要 Python 相關的職位的人才。



2、城市需求分析





從上圖分析,可以發現,需求量主要集中在中國三大經濟圈:京津冀,長三角,珠三角。主要分佈在北京(40%)、上海(16%)、深圳(15%)、廣州(6%)、成都(6%)和杭州(6%)這 6 個城市。而北京的網際網路創業氣氛冠絕中國,註冊在北京的網際網路公司遠遠高於在其他城市的公司,需求量也是最大的。


3、薪酬與工作經驗分析







從工作經驗的要求來看,大部分集中在 3-5 年和 1-3 年這兩個區間,至於工作經驗和薪酬之間的相關性,觀察發現,1-3 年工作經驗的薪酬普遍在 15-25K,符合正態分佈的規律,3-5 年工作經驗的薪酬普遍在 15k-25k 和 25k-50k 這兩個區間,以 15k-25k 這個區間的居多。達到 5-10 年工作經驗的,薪酬在 25k-50K 這個區間的居多。


4、學歷要求和工作經驗分析




從學歷要求來看,大部分都要求至少本科以上,這部分佔了約 80% 的比例。所以不要在相信讀書無用論這種觀點了,學歷至少是工作的敲門磚。


工作經驗上,普遍要求是 1-5 年,這部分佔了 84% 的比例。1年以下和經驗不限的,佔了約 9%,5-10 年的佔了約 7% 的比例。


總結


TIOBE 8 月程式語言指數排行榜已經公佈了,排名前三的雖然依舊是 Java、C、C++。但 Python 非常接近 TIOBE 索引的前 3 位。Python 這樣的上漲趨勢,同樣可以在 TIOBE 索引排行中體現,網際網路業界也開始普遍採用 Python。Python 程式語言最初是 Perl 的繼承者,用於編寫構建指令碼和各種粘合軟體。但後來逐漸進入其他領域。如今,在大型嵌入式系統中執行 Python 是很常見的。因此,Python 完全有可能進入前三名,甚至在未來取代 Java 成為新的第一名。



從目前 Python 的就業前景來看,總結如下:



  • Python 就業情況樂觀,從 TIOBE 8 月程式語言指數排行榜以及百度指數的搜尋數來看,Python 的受歡迎程度越來越高。





  • 在中國地區,Python 相關職位的需求量,依然集中在三大經濟圈,特別是在北京、上海、深圳這幾個城市。從行業需求來看,主要集中在移動網際網路、資料服務、大資料分析等行業。




  • 從拉勾網的資料分析可知,大部分 Python 的相關職位都要求在本科和本科以上,工作經驗要求在 1-5 年的居多。因為 Python 在大資料和人工智慧領域的爆發性發展, 導致 Python 方向崗位的薪水在水漲船高,從資料分析來看,月薪在 10K-50K 不等。



注,文中原始碼已上傳至 GitHub,地址:https://github.com/liaolongfei/lagou/


作者簡介:lowelong,國內某網際網路公司測試工程師,目前學習 Python 中。


宣告:本文為 CSDN 「技術頭條」欄目獨家投稿文章。如需轉載,請微信聯絡 God-I-love-u。


一生只為尋歡笑的 Linux 之父 Linus Torvalds 說過一句至理名言 —— 「Talk is cheap. Show me the code」,這正是 CSDN 「技術頭條」欄目所秉持的初衷和願景。針對開發者們所面臨的技術痛點,面向所有開發者,一起用程式碼見真章。如果你有優質的技術文章,從新技術的探索到業務落地實踐,均歡迎投稿,一起 Show code!


徵稿啦


CSDN 公眾號秉持著「與千萬技術人共成長」理念,不僅以「極客頭條」、「暢言」欄目在第一時間以技術人的獨特視角描述技術人關心的行業焦點事件,更有「技術頭條」專欄,深度解讀行業內的熱門技術與場景應用,讓所有的開發者緊跟技術潮流,保持警醒的技術嗅覺,對行業趨勢、技術有更為全面的認知。


如果你有優質的文章,或是行業熱點事件、技術趨勢的真知灼見,或是深度的應用實踐、場景方案等的新見解,歡迎聯絡 CSDN 投稿,聯繫方式:_1118,請備註投稿+姓名+公司職位),郵箱([email protected])。





http://www.kubonews.com/2018083029444.html

心情煩悶需要新鮮事刺激一下嗎?請上:http://www.kubonews.com

沒有留言:

張貼留言