日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

Python爬取Boss直聘,幫你獲取全國(guó)各類職業(yè)薪酬榜

系統(tǒng) 2166 0

今天想和大家聊聊Python與爬蟲(chóng)

python之所以能迅速風(fēng)靡全國(guó),和大街小巷各種的培訓(xùn)機(jī)構(gòu)脫不開(kāi)關(guān)系。

一會(huì)pythonAI未來(lái)以來(lái),一會(huì)兒4個(gè)月培養(yǎng)人工智能與機(jī)器學(xué)習(xí)頂尖人才,更有甚者什么一周成就爬蟲(chóng)分析師...

我這一把年紀(jì)了,膽子小只敢在自己的公眾號(hào)里說(shuō)說(shuō)。至于出去了,你們?cè)搶?shí)力互吹、生猛造勢(shì)的,我看看就好不說(shuō)話。

網(wǎng)上經(jīng)??吹脚老x(chóng)的文章,什么爬了幾十萬(wàn)數(shù)據(jù),一把擼下來(lái)幾千萬(wàn)評(píng)論的,聽(tīng)起來(lái)高大上又牛逼。

但其實(shí)爬蟲(chóng)工程師,你看網(wǎng)上有幾個(gè)招聘的?為什么,因?yàn)閿?shù)據(jù)有價(jià)!

各大廠做什么網(wǎng)絡(luò)解決方案的,怎么解決?不得先把各大運(yùn)營(yíng)商數(shù)據(jù)買回來(lái)分析了才去解決嗎?天下哪有白吃的午餐。

爬蟲(chóng)面臨的問(wèn)題

  1. 不再是單純的數(shù)據(jù)一把抓
    多數(shù)的網(wǎng)站還是請(qǐng)求來(lái)了,一把將所有數(shù)據(jù)塞進(jìn)去返回,但現(xiàn)在更多的網(wǎng)站使用數(shù)據(jù)的異步加載,爬蟲(chóng)不再像之前那么方便
    很多人說(shuō)js異步加載與數(shù)據(jù)解析,爬蟲(chóng)可以做到啊,恩是的,無(wú)非增加些工作量,那是你沒(méi)遇到牛逼的前端,多數(shù)的解決辦法只能靠渲染瀏覽器抓取,效率低下,接著往下走
  2. 千姿百態(tài)的登陸驗(yàn)證
    從12306的說(shuō)說(shuō)下面哪個(gè)糖是奶糖,到現(xiàn)在各大網(wǎng)站的滑動(dòng)拼圖、漢子點(diǎn)擊解鎖,這些操作都是在為了阻止爬蟲(chóng)的自動(dòng)化運(yùn)行。
    你說(shuō)可以先登錄了復(fù)制cookie,但cookie也有失效期吧?
  3. 反爬蟲(chóng)機(jī)制
    何為反爬蟲(chóng)?犀利的解釋網(wǎng)上到處搜,簡(jiǎn)單的邏輯我講給你聽(tīng)。你幾秒鐘訪問(wèn)了我的網(wǎng)站一千次,不好意思,我把你的ip禁掉,一段時(shí)間你別來(lái)了。
    很多人又說(shuō)了,你也太菜了吧,不知道有爬蟲(chóng)ip代理池的開(kāi)源項(xiàng)目 IPProxys 嗎?那我就呵呵了,幾個(gè)人真的現(xiàn)在用過(guò)免費(fèi)的ip代理池,你去看看現(xiàn)在的免費(fèi)代理池,有幾個(gè)是可用的!
    再說(shuō)了,你通過(guò)IPProxys代理池,獲取到可用的代理訪問(wèn)人家網(wǎng)站,人家網(wǎng)站不會(huì)用同樣的辦法查到可用的代理先一步封掉嗎?然后你只能花錢去買付費(fèi)的代理
  4. 數(shù)據(jù)源頭封鎖
    平時(shí)大家看的什么爬爬豆瓣電影網(wǎng)站啊,收集下某寶評(píng)論啊....這些都是公開(kāi)數(shù)據(jù)。但現(xiàn)在更多的數(shù)據(jù)逐步走向閉源化。數(shù)據(jù)的價(jià)值越來(lái)越大,沒(méi)有數(shù)據(jù)獲取的源頭,爬蟲(chóng)面臨什么問(wèn)題?

個(gè)人面對(duì)爬蟲(chóng)的態(tài)度

學(xué)習(xí)爬蟲(chóng),可以讓你多掌握一門技術(shù),但個(gè)人勸你不要在這條路走的太深。沒(méi)事兒爬點(diǎn)小東西,學(xué)習(xí)下網(wǎng)絡(luò)知識(shí),掌握些網(wǎng)頁(yè)解析技巧就好了。再牛逼的爬蟲(chóng)框架,也解決不了你沒(méi)數(shù)據(jù)的苦惱。

說(shuō)說(shuō)今天內(nèi)容

扯了一圈了,該回到主題了。
上面說(shuō)了一堆的爬蟲(chóng)這不好那不好,結(jié)果我今天發(fā)的文章確是爬蟲(chóng)的,自己打自己的臉?
其實(shí)我只是想說(shuō)說(shuō)網(wǎng)站數(shù)據(jù)展示與分析的技巧...恰巧Boss直聘就做的很不錯(cuò)。怎么不錯(cuò)?一點(diǎn)點(diǎn)分析...

  • 數(shù)據(jù)共享
    先來(lái)看一張圖:

Python爬取Boss直聘,幫你獲取全國(guó)各類職業(yè)薪酬榜_第1張圖片

大興安嶺

我選擇黑龍江省的大興安嶺,去看看那里有招聘python的沒(méi),多數(shù)系統(tǒng)查詢不到數(shù)據(jù)就會(huì)給你提示未獲取到相關(guān)數(shù)據(jù),但Boss直聘會(huì)悄悄地吧黑龍江省的python招聘信息給你顯示處理,夠雞~賊。

  • 數(shù)據(jù)限制
    大興安嶺沒(méi)有搞python的,那我們?nèi)ト珖?guó)看看吧:

Python爬取Boss直聘,幫你獲取全國(guó)各類職業(yè)薪酬榜_第2張圖片

全國(guó)數(shù)據(jù)

這里差一點(diǎn)就把我坑了,我開(kāi)始天真的以為,全國(guó)只有300條(一頁(yè)30條,共10也)python招聘信息。
然后我回過(guò)頭去看西安的,也只有10頁(yè),然后想著修改下他的get請(qǐng)求parameters,沒(méi)卵用。

這有啥用?仔細(xì)想...一方面可以做到放置咱們爬蟲(chóng)一下獲取所有的數(shù)據(jù),但這只是你自作多情,這東西是商機(jī)!
每天那么多的商家發(fā)布招聘信息,進(jìn)入不了top100,別人想看都看不到你的消息,除非搜索名字。那么如何排名靠前?答案就是最后倆字,靠錢。你是Boss直聘的會(huì)員,你發(fā)布的就會(huì)靠前....

  • 偷換概念
    依舊先看圖:

Python爬取Boss直聘,幫你獲取全國(guó)各類職業(yè)薪酬榜_第3張圖片

大雜燴

  • 我搜索的是ruby,你資料不夠,其他來(lái)湊....
  • ip解析
    老套路,再來(lái)看一張圖:

Python爬取Boss直聘,幫你獲取全國(guó)各類職業(yè)薪酬榜_第4張圖片

封“神”榜

感覺(jué)人生已經(jīng)到達(dá)了高潮,感覺(jué)人生已經(jīng)到達(dá)了巔峰

Boss直聘的服務(wù)器里,留著我的痕跡,多么驕傲的事情啊。你們想不想和我一樣?只需要3秒鐘....
三秒鐘內(nèi)你的訪問(wèn)量能超過(guò)1000,妥妥被封!

  • 反反反爬蟲(chóng)
    咱們正常的叫爬蟲(chóng),它不讓我們爬,這叫反爬蟲(chóng),然后我們用ip代理池的ip,這叫反反爬蟲(chóng)。結(jié)果你發(fā)現(xiàn),人家早就把可用的代理池先一步封了,這叫反反反爬蟲(chóng)....
    免費(fèi)代理池中,很多代理是不可用或者需要輸入密碼的。好不容易找到一些能用的列表,拉過(guò)來(lái)添加上發(fā)現(xiàn)早就被封掉了,也許是它提前禁掉,也許是別人用過(guò)被封了,但結(jié)局就是你千辛萬(wàn)苦找來(lái)的,往往最終還是失敗的。

那么我們?cè)撛趺崔k

  1. 設(shè)置不同的User-Agent
    使用 pip install fake-useragent 安裝后獲取多種User-Agent,但其實(shí)本地保存上幾十個(gè),完全夠了....
  2. 不要太夯(大力)
    適當(dāng)?shù)臏p慢你的速度,別人不會(huì)覺(jué)得是你菜....別覺(jué)得一秒爬幾千比一秒爬幾百的人牛逼(快槍手子彈打完的早....不算開(kāi)車吧?)。
  3. 購(gòu)買付費(fèi)的代理
    為什么我跳過(guò)了說(shuō)免費(fèi)的代理?因?yàn)楝F(xiàn)在搞爬蟲(chóng)的人太多了,免費(fèi)的基本早就列入各大網(wǎng)站的黑名單了。

說(shuō)說(shuō)今天的內(nèi)容

爬取全國(guó)熱點(diǎn)城市的職業(yè),然后對(duì)各大城市的薪資進(jìn)行比較。

你想爬什么職業(yè),自己寫關(guān)鍵字即可.....

我當(dāng)然關(guān)注的是python了,所以解析到的原始數(shù)據(jù)如下:

Python爬取Boss直聘,幫你獲取全國(guó)各類職業(yè)薪酬榜_第5張圖片

先來(lái)看看python的薪酬榜:

Python爬取Boss直聘,幫你獲取全國(guó)各類職業(yè)薪酬榜_第6張圖片

python薪酬榜

看一下西安的排位,薪資平均真的好低.....

至于你說(shuō)薪資范圍:什么15-20K?放心90%的人入職都只會(huì)給你15K的,那10%的人不是你,不是你。
再來(lái)看看ruby的:

Python爬取Boss直聘,幫你獲取全國(guó)各類職業(yè)薪酬榜_第7張圖片

Ruby薪酬榜

看這感覺(jué)比Python高很多啊....但其實(shí)呢?跟百度人均公司3W+一樣,你拿人均算?光幾個(gè)總裁年薪上億的,就拉上去了....

但還是可以看到一點(diǎn),西安的薪酬還是好低......

代碼

代碼其實(shí)沒(méi)有太多講的,篇幅最多的內(nèi)容,估計(jì)就是我的User-Agent了....

            
              # -*- coding: utf-8 -*-
# @Author   : 王翔
# @JianShu  : 清風(fēng)Python
# @Date     : 2019/6/14 22:23
# @Software : PyCharm
# @version  :Python 3.6.8
# @File     : BossCrawler.py

import requests
from bs4 import BeautifulSoup
import csv
import random
import time
import argparse
from pyecharts.charts import Line
import pandas as pd


class BossCrawler:
    def __init__(self, query):

        self.query = query
        self.filename = 'boss_info_%s.csv' % self.query
        self.city_code_list = self.get_city()
        self.boss_info_list = []
        self.csv_header = ["city", "profession", "salary", "company"]

    @staticmethod
    def getheaders():
        user_list = [
            "Opera/9.80 (X11; Linux i686; Ubuntu/14.10) Presto/2.12.388 Version/12.16",
            "Opera/9.80 (Windows NT 6.0) Presto/2.12.388 Version/12.14",
            "Mozilla/5.0 (Windows NT 6.0; rv:2.0) Gecko/20100101 Firefox/4.0 Opera 12.14",
            "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0) Opera 12.14",
            "Opera/12.80 (Windows NT 5.1; U; en) Presto/2.10.289 Version/12.02",
            "Opera/9.80 (Windows NT 6.1; U; es-ES) Presto/2.9.181 Version/12.00",
            "Opera/9.80 (Windows NT 5.1; U; zh-sg) Presto/2.9.181 Version/12.00",
            "Opera/12.0(Windows NT 5.2;U;en)Presto/22.9.168 Version/12.00",
            "Opera/12.0(Windows NT 5.1;U;en)Presto/22.9.168 Version/12.00",
            "Mozilla/5.0 (Windows NT 5.1) Gecko/20100101 Firefox/14.0 Opera/12.0",
            "Opera/9.80 (Windows NT 6.1; WOW64; U; pt) Presto/2.10.229 Version/11.62",
            "Opera/9.80 (Windows NT 6.0; U; pl) Presto/2.10.229 Version/11.62",
            "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; fr) Presto/2.9.168 Version/11.52",
            "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; de) Presto/2.9.168 Version/11.52",
            "Opera/9.80 (Windows NT 5.1; U; en) Presto/2.9.168 Version/11.51",
            "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; de) Opera 11.51",
            "Opera/9.80 (X11; Linux x86_64; U; fr) Presto/2.9.168 Version/11.50",
            "Opera/9.80 (X11; Linux i686; U; hu) Presto/2.9.168 Version/11.50",
            "Opera/9.80 (X11; Linux i686; U; ru) Presto/2.8.131 Version/11.11",
            "Opera/9.80 (X11; Linux i686; U; es-ES) Presto/2.8.131 Version/11.11",
            "Mozilla/5.0 (Windows NT 5.1; U; en; rv:1.8.1) Gecko/20061208 Firefox/5.0 Opera 11.11",
            "Opera/9.80 (X11; Linux x86_64; U; bg) Presto/2.8.131 Version/11.10",
            "Opera/9.80 (Windows NT 6.0; U; en) Presto/2.8.99 Version/11.10",
            "Opera/9.80 (Windows NT 5.1; U; zh-tw) Presto/2.8.131 Version/11.10",
            "Opera/9.80 (Windows NT 6.1; Opera Tablet/15165; U; en) Presto/2.8.149 Version/11.1",
            "Opera/9.80 (X11; Linux x86_64; U; Ubuntu/10.10 (maverick); pl) Presto/2.7.62 Version/11.01",
            "Opera/9.80 (X11; Linux i686; U; ja) Presto/2.7.62 Version/11.01",
            "Opera/9.80 (X11; Linux i686; U; fr) Presto/2.7.62 Version/11.01",
            "Opera/9.80 (Windows NT 6.1; U; zh-tw) Presto/2.7.62 Version/11.01",
            "Opera/9.80 (Windows NT 6.1; U; zh-cn) Presto/2.7.62 Version/11.01",
            "Opera/9.80 (Windows NT 6.1; U; sv) Presto/2.7.62 Version/11.01",
            "Opera/9.80 (Windows NT 6.1; U; en-US) Presto/2.7.62 Version/11.01",
            "Opera/9.80 (Windows NT 6.1; U; cs) Presto/2.7.62 Version/11.01",
            "Opera/9.80 (Windows NT 6.0; U; pl) Presto/2.7.62 Version/11.01",
            "Opera/9.80 (Windows NT 5.2; U; ru) Presto/2.7.62 Version/11.01",
            "Opera/9.80 (Windows NT 5.1; U;) Presto/2.7.62 Version/11.01",
            "Opera/9.80 (Windows NT 5.1; U; cs) Presto/2.7.62 Version/11.01",
            "Mozilla/5.0 (Windows NT 6.1; U; nl; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Opera 11.01",
            "Mozilla/5.0 (Windows NT 6.1; U; de; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Opera 11.01",
            "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; de) Opera 11.01",
            "Opera/9.80 (X11; Linux x86_64; U; pl) Presto/2.7.62 Version/11.00",
            "Opera/9.80 (X11; Linux i686; U; it) Presto/2.7.62 Version/11.00",
            "Opera/9.80 (Windows NT 6.1; U; zh-cn) Presto/2.6.37 Version/11.00",
            "Opera/9.80 (Windows NT 6.1; U; pl) Presto/2.7.62 Version/11.00",
            "Opera/9.80 (Windows NT 6.1; U; ko) Presto/2.7.62 Version/11.00",
            "Opera/9.80 (Windows NT 6.1; U; fi) Presto/2.7.62 Version/11.00",
            "Opera/9.80 (Windows NT 6.1; U; en-GB) Presto/2.7.62 Version/11.00",
            "Opera/9.80 (Windows NT 6.1 x64; U; en) Presto/2.7.62 Version/11.00",
            "Opera/9.80 (Windows NT 6.0; U; en) Presto/2.7.39 Version/11.00"
        ]
        user_agent = random.choice(user_list)
        headers = {'User-Agent': user_agent}
        return headers

    def get_city(self):
        headers = self.getheaders()
        r = requests.get("http://www.zhipin.com/wapi/zpCommon/data/city.json", headers=headers)
        data = r.json()
        return [city['code'] for city in data['zpData']['hotCityList'][1:]]

    def get_response(self, url, params=None):
        headers = self.getheaders()
        r = requests.get(url, headers=headers, params=params)
        r.encoding = 'utf-8'
        soup = BeautifulSoup(r.text, "lxml")
        return soup

    def get_url(self):
        for city_code in self.city_code_list:
            url = "https://www.zhipin.com/c%s/" % city_code
            self.per_page_info(url)
            time.sleep(10)

    def per_page_info(self, url):
        for page_num in range(1, 11):
            params = {"query": self.query, "page": page_num}
            soup = self.get_response(url, params)
            lines = soup.find('div', class_='job-list').select('ul > li')
            if not lines:
                # 代表沒(méi)有數(shù)據(jù)了,換下一個(gè)城市
                return
            for line in lines:
                info_primary = line.find('div', class_="info-primary")
                city = info_primary.find('p').text.split(' ')[0]
                job = info_primary.find('div', class_="job-title").text
                # 過(guò)濾答非所謂的招聘信息
                if self.query.lower() not in job.lower():
                    continue
                salary = info_primary.find('span', class_="red").text.split('-')[0].replace('K', '')
                company = line.find('div', class_="info-company").find('a').text.lower()
                result = dict(zip(self.csv_header, [city, job, salary, company]))
                print(result)
                self.boss_info_list.append(result)

    def write_result(self):
        with open(self.filename, "w+", encoding='utf-8', newline='') as f:
            f_csv = csv.DictWriter(f, self.csv_header)
            f_csv.writeheader()
            f_csv.writerows(self.boss_info_list)

    def read_csv(self):
        data = pd.read_csv(self.filename, sep=",", header=0)
        data.groupby('city').mean()['salary'].to_frame('salary').reset_index().sort_values('salary', ascending=False)
        result = data.groupby('city').apply(lambda x: x.mean()).round(1)['salary'].to_frame(
            'salary').reset_index().sort_values('salary', ascending=False)
        print(result)
        charts_bar = (
            Line()
                .set_global_opts(
                title_opts={"text": "全國(guó)%s薪酬榜" % self.query})
                .add_xaxis(result.city.values.tolist())
                .add_yaxis("salary", result.salary.values.tolist())
        )
        charts_bar.render('%s.html' % self.query)


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("-k", "--keyword", help="請(qǐng)?zhí)顚懰璨樵兊年P(guān)鍵字")
    args = parser.parse_args()
    if not args.keyword:
        print(parser.print_help())
    else:
        main = BossCrawler(args.keyword)
        main.get_url()
        main.write_result()
        main.read_csv()
            
          

好了,今天的內(nèi)容就到這里,如果覺(jué)得有幫助,記得點(diǎn)贊支持。歡迎大家關(guān)注筆者的公眾號(hào)【清風(fēng)Python】。


來(lái)源:清風(fēng)Python


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 托克托县| 定边县| 塘沽区| 德安县| 珠海市| 义乌市| 扎鲁特旗| 肥东县| 巢湖市| 民县| 汝州市| 潮州市| 新宾| 金阳县| 上林县| 宝坻区| 梁河县| 华安县| 融水| 信阳市| 台东市| SHOW| 邛崃市| 祁连县| 土默特左旗| 汝南县| 巴南区| 阿坝| 固原市| 泾川县| 方正县| 鹿邑县| 宜章县| 民权县| 公主岭市| 盱眙县| 嘉善县| 屯门区| 咸阳市| 新宁县| 宁波市|