當前位置:
首頁 > 知識 > Python 爬蟲實踐:淺談數據分析崗位

Python 爬蟲實踐:淺談數據分析崗位

(給

Python開發者

加星標,提升Python技能




轉自:法納斯特 




講道理,pyspider確實是一款優秀的爬蟲框架,我們可以利用它快速方便地實現一個頁面的抓取。




不過帶來便捷性的同時,也有它的局限性,複雜頁面不好爬取。



在本次的數據爬取中,BOSS直聘是成功使用pyspider。但拉勾網卻不行,因為拉勾網的數據是Ajax載入的。




拉勾網崗位數據請求的網址是不變的,改變的是

表單數據

表單數據隨著頁數改變

請求方式為POST。

這裡沒辦法在pyspider里用循環遍歷來獲取每一頁的數據。



也許是我對pyspider框架了解的不夠,還達不到得心應手。所以最後拉勾網的爬取,採用平常的辦法,在PyCharm中自行編寫程序。




本次通過對BOSS直聘,拉勾網數據分析崗數據分析,了解數據分析崗的行業情況,也以此來了解從事數據分析所需要的技能。






/ 01 / 網頁分析







獲取BOSS直聘索引頁信息,主要是崗位名稱、薪資、地點、工作年限、學歷要求,公司名稱、類型、狀態、規模。




本來一開始是想對詳情頁分析的,還可以獲取詳情頁里的工作內容和工作技能需求。



然後由於請求太多,就放棄了。索引頁有10頁,1頁有30個崗位,

一個詳情頁就需要一個請求,

算起來一共有300個請求。




我是到了第2頁(60個請求),就出現了訪問過於頻繁的警告。




而只獲取索引頁信息的話,只有10個請求,基本上沒什麼問題,外加也不想去鼓搗代理IP,所以來點簡單的。



到時候做數據挖掘崗位的數據時,看看放慢時間能否獲取成功。







獲取拉勾網索引頁信息,主要是崗位名稱、地點、薪資、工作年限、學歷要求,公司名稱、類型、狀態、規模,工作技能,工作福利。




網頁為Ajax請求,採用PyCharm編寫代碼,輕車熟路。





/ 02 / 數據獲取




01 pyspider獲取BOSS直聘數據



pyspider的安裝很簡單,直接在命令行pip3 install pyspider即可。




這裡因為之前沒有安裝pyspider對接的PhantomJS(處理JavaScript渲染的頁面)。




所以需要從網站下載下來它的exe文件,將其放入Python的exe文件所在的文件夾下。



最後在命令行輸入pyspider all,即可運行pyspider。




在瀏覽器打開網址http://localhost:5000/,創建項目,添加項目名稱,輸入請求網址,得到如下圖。







最後在pyspider的腳本編輯器里編寫代碼,結合左邊的反饋情況,對代碼加以改正。







腳本編輯器具體代碼如下。



#!/usr/bin/env python


# -*- encoding: utf-8 -*-


# Project: BOSS

from

 pyspider.libs.base_handler 

import

 *

import

 pymysql

import

 random

import

 time

import

 re

count = 

0

class

 

Handler

(BaseHandler)

:


    

# 添加請求頭,否則出現403報錯


    crawl_config = {

"headers"

: {

"User-Agent"

"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"

}}

    

def

 

__init__

(self)

:


        

# 連接資料庫


        self.db = pymysql.connect(host=

"127.0.0.1"

, user=

"root"

, password=

"774110919"

, port=

3306

, db=

"boss_job"

, charset=

"utf8mb4"

)

    

def

 

add_Mysql

(self, id, job_title, job_salary, job_city, job_experience, job_education, company_name, company_type, company_status, company_people)

:


        

# 將數據寫入資料庫中


        

try

:
            cursor = self.db.cursor()
            sql = 

"insert into job(id, job_title, job_salary, job_city, job_experience, job_education, company_name, company_type, company_status, company_people) values ("%d", "%s", "%s", "%s", "%s", "%s", "%s", "%s", "%s", "%s")"

 % (id, job_title, job_salary, job_city, job_experience, job_education, company_name, company_type, company_status, company_people);
            print(sql)
            cursor.execute(sql)
            print(cursor.lastrowid)
            self.db.commit()
        

except

 Exception 

as

 e:
            print(e)
            self.db.rollback()

    @every(minutes=

24

 * 

60

)
    

def

 

on_start

(self)

:


        

# 因為pyspider默認是HTTP請求,對於HTTPS(加密)請求,需要添加validate_cert=False,否則599/SSL報錯


        self.crawl(

"https://www.zhipin.com/job_detail/?query=%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90&scity=100010000&industry=&position="

, callback=self.index_page, validate_cert=

False

)

    @config(age=

10

 * 

24

 * 

60

 * 

60

)
    

def

 

index_page

(self, response)

:


        time.sleep(random.randint(

2

5

))
        

for

 i 

in

 response.doc(

"li > div"

).items():
            

# 設置全局變數


            

global

 count
            count += 

1


            

# 崗位名稱


            job_title = i(

".job-title"

).text()
            print(job_title)
            

# 崗位薪水


            job_salary = i(

".red"

).text()
            print(job_salary)
            

# 崗位地點


            city_result = re.search(

"(.*?)<em class="

, i(

".info-primary > p"

).html())
            job_city = city_result.group(

1

).split(

" "

)[

0

]
            print(job_city)
            

# 崗位經驗


            experience_result = re.search(

"<em class="vline"/>(.*?)<em class="vline"/>"

, i(

".info-primary > p"

).html())
            job_experience = experience_result.group(

1

)
            print(job_experience)
            

# 崗位學歷


            job_education = i(

".info-primary > p"

).text().replace(

" "

""

).replace(city_result.group(

1

).replace(

" "

""

), 

""

).replace(experience_result.group(

1

).replace(

" "

""

),

""

)
            print(job_education)
            

# 公司名稱


            company_name = i(

".info-company a"

).text()
            print(company_name)
            

# 公司類型


            company_type_result = re.search(

"(.*?)<em class="

, i(

".info-company p"

).html())
            company_type = company_type_result.group(

1

)
            print(company_type)
            

# 公司狀態


            company_status_result = re.search(

"<em class="vline"/>(.*?)<em class="vline"/>"

, i(

".info-company p"

).html())
            

if

 company_status_result:
                company_status = company_status_result.group(

1

)
            

else

:
                company_status = 

"無信息"


            print(company_status)
            

# 公司規模


            company_people = i(

".info-company p"

).text().replace(company_type, 

""

).replace(company_status,

""

)
            print(company_people + 

"
"

)
            

# 寫入資料庫中


            self.add_Mysql(count, job_title, job_salary, job_city, job_experience, job_education, company_name, company_type, company_status, company_people)
        

# 獲取下一頁信息


        next = response.doc(

".next"

).attr.href
        

if

 next != 

"javascript:;"

:
            self.crawl(next, callback=self.index_page, validate_cert=

False

)
        

else

:
            print(

"The Work is Done"

)
        

# 詳情頁信息獲取,由於訪問次數有限制,不使用


        

#for each in response.doc(".name > a").items():


            

#url = each.attr.href


            

#self.crawl(each.attr.href, callback=self.detail_page, validate_cert=False)

    @config(priority=

2

)
    

def

 

detail_page

(self, response)

:


        

# 詳情頁信息獲取,由於訪問次數有限制,不使用


        message_job = response.doc(

"div > .info-primary > p"

).text()
        city_result = re.findall(

"城市:(.*?)經驗"

, message_job)
        experience_result = re.findall(

"經驗:(.*?)學歷"

, message_job)
        education_result = re.findall(

"學歷:(.*)"

, message_job)

        message_company = response.doc(

".info-company > p"

).text().replace(response.doc(

".info-company > p > a"

).text(),

""

)
        status_result = re.findall(

"(.*?)d"

, message_company.split(

" "

)[

0

])
        people_result = message_company.split(

" "

)[

0

].replace(status_result[

0

], 

""

)

        

return

 {
            

"job_title"

: response.doc(

"h1"

).text(),
            

"job_salary"

: response.doc(

".info-primary .badge"

).text(),
            

"job_city"

: city_result[

0

],
            

"job_experience"

: experience_result[

0

],
            

"job_education"

: education_result[

0

],
            

"job_skills"

: response.doc(

".info-primary > .job-tags > span"

).text(),
            

"job_detail"

: response.doc(

"div"

).filter(

".text"

).eq(

0

).text().replace(

"
"

""

),
            

"company_name"

: response.doc(

".info-company > .name > a"

).text(),
            

"company_status"

: status_result[

0

],
            

"company_people"

: people_result,
            

"company_type"

: response.doc(

".info-company > p > a"

).text(),
        }




獲取BOSS直聘數據分析崗數據如下。







02 PyCharm獲取拉勾網數據



import

 requests

import

 pymysql

import

 random

import

 time

import

 json

count = 

0


# 設置請求網址及請求頭參數


url = 

"https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false"


headers = {
    

"User-Agent"

"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"

,
    

"Cookie"

"你的Cookie值"

,
    

"Accept"

"application/json, text/javascript, */*; q=0.01"

,
    

"Connection"

"keep-alive"

,
    

"Host"

"www.lagou.com"

,
    

"Origin"

"https://www.lagou.com"

,
    

"Referer"

"ttps://www.lagou.com/jobs/list_%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90?labelWords=sug&fromSearch=true&suginput=shuju"


}

# 連接資料庫


db = pymysql.connect(host=

"127.0.0.1"

, user=

"root"

, password=

"774110919"

, port=

3306

, db=

"lagou_job"

, charset=

"utf8mb4"

)

def

 

add_Mysql

(id, job_title, job_salary, job_city, job_experience, job_education, company_name, company_type, company_status, company_people, job_tips, job_welfare)

:


    

# 將數據寫入資料庫中


    

try

:
        cursor = db.cursor()
        sql = 

"insert into job(id, job_title, job_salary, job_city, job_experience, job_education, company_name, company_type, company_status, company_people, job_tips, job_welfare) values ("%d", "%s", "%s", "%s", "%s", "%s", "%s", "%s", "%s", "%s", "%s", "%s")"

 % (id, job_title, job_salary, job_city, job_experience, job_education, company_name, company_type, company_status, company_people, job_tips, job_welfare);
        print(sql)
        cursor.execute(sql)
        print(cursor.lastrowid)
        db.commit()
    

except

 Exception 

as

 e:
        print(e)
        db.rollback()

def

 

get_message

()

:


    

for

 i 

in

 range(

1

31

):
        print(

"第"

 + str(i) + 

"頁"

)
        time.sleep(random.randint(

10

20

))
        data = {
            

"first"

"false"

,
            

"pn"

: i,
            

"kd"

"數據分析"


        }
        response = requests.post(url=url, data=data, headers=headers)
        result = json.loads(response.text)
        job_messages = result[

"content"

][

"positionResult"

][

"result"

]
        

for

 job 

in

 job_messages:
            

global

 count
            count += 

1


            

# 崗位名稱


            job_title = job[

"positionName"

]
            print(job_title)
            

# 崗位薪水


            job_salary = job[

"salary"

]
            print(job_salary)
            

# 崗位地點


            job_city = job[

"city"

]
            print(job_city)
            

# 崗位經驗


            job_experience = job[

"workYear"

]
            print(job_experience)
            

# 崗位學歷


            job_education = job[

"education"

]
            print(job_education)
            

# 公司名稱


            company_name = job[

"companyShortName"

]
            print(company_name)
            

# 公司類型


            company_type = job[

"industryField"

]
            print(company_type)
            

# 公司狀態


            company_status = job[

"financeStage"

]
            print(company_status)
            

# 公司規模


            company_people = job[

"companySize"

]
            print(company_people)
            

# 工作技能


            

if

 len(job[

"positionLables"

]) > 

0

:
                job_tips = 

","

.join(job[

"positionLables"

])
            

else

:
                job_tips = 

"None"


            print(job_tips)
            

# 工作福利


            job_welfare = job[

"positionAdvantage"

]
            print(job_welfare + 

"

"

)
            

# 寫入資料庫


            add_Mysql(count, job_title, job_salary, job_city, job_experience, job_education, company_name, company_type, company_status, company_people, job_tips, job_welfare)

if

 __name__ == 

"__main__"

:
    get_message()




獲取拉勾網數據分析崗數據如下。







這裡的資料庫都是自己在外面創建的,之前也用了好多回,就不貼代碼細說了。






/ 03 / 數據可視化




01 城市分布圖










崗位的分布情況,這裡可以看出崗位大多都分布在東部地區,中部也有一些。




02 城市分布熱力圖










京津冀、長三角、珠三角密集度不相上下,成都重慶地區也有一小些需求。




可以說北上廣深,這四個一線城市包攬了大部分的崗位需求。




03 工作經驗薪水圖










這裡通過看箱形圖的四分位及中間值,大致能看出隨著工作年限的增長,薪資也是一路上升。




BOSS直聘里,1年以內工作經驗的薪資,有個最高4萬多的,這肯定是不合理的。




於是就去資料庫看了下,其實那個崗位要求是3年以上,但實際給的標籤卻是1年以內。




所以說數據來源提供的

數據的準確性

很重要。




04 學歷薪水圖










總的來說「碩士」>

「本科」>「大專」,當然大專、本科中也有高薪水的。




畢竟越往後能力就越重要,學歷算是一個

重要的加分項




05 公司狀態薪水圖










這裡的數據沒什麼特點,就當了解下這些概念。




一個公司的發展,可以是從

天使輪

一直到

上市公司

」,路途坎坷。




06 公司規模薪水圖










正常來說,公司規模越大,薪水應該會越高。




畢竟大廠的工資擺在那裡,想不知道都難。




不過這裡沒能體現出來差距,倒是發現人數最少的公司,最高工資給的不高,難不成是初期缺錢?




07 公司類型TOP10










數據分析崗主要集中在互聯網行業,

「金融」「地產」「教育」「醫療」「遊戲」也有所涉及。




大部分崗位需求都集中

第三產業

上。




08 工作技能圖







這個算是本次的重點,這些技能

將會是日後學習的重點。




「數據挖掘」「SQL」「BI」「數據運營」「SPSS」「資料庫」「MySQL」

等等。




09 工作福利圖







這裡可以看出大部分重點都圍繞著

「五險一金」「福利多」「團隊氛圍好」「晉陞空間大」「行業大牛領頭」上。




要是哪家公司都具備了,那簡直就是要上天。




不過你我都清楚

,這是不存在的,就算可能存在,也只是別人家的公司而已~






/ 04 / 總結




最後貼兩張BOSS直聘以及拉勾網薪水TOP20,以此來作為勉

勵。




01 

BOSS直聘薪水TOP20







02 拉勾網薪水TOP20







畢竟我們不能僅僅當條鹹魚,我們要當就當一隻

有夢想的鹹魚!!!




  公眾號回復 1207,即可獲取源碼。






推薦閱讀


(點擊標題可跳轉閱讀)



手把手教你寫網路爬蟲(2):迷你爬蟲架構



爬蟲進階:反反爬蟲技巧


Python 爬蟲神器 PyQuery 的使用方法





覺得本文對你有幫助?請分享給更多人


關注「Python開發者」加星標,提升Python技能




喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Python開發者 的精彩文章:

TAG:Python開發者 |