美文网首页python爬虫日记本大数据 爬虫Python AI Sql爬虫专题
利用python分析2018智联招聘全国各个城市的职位数排名

利用python分析2018智联招聘全国各个城市的职位数排名

作者: 爱吃饭真是太好了 | 来源:发表于2018-01-18 15:27 被阅读97次

    新年快到了,工作了一年你,躺在床上,退下一身的疲怠,是否也曾向往去到一个新的城市工作和生活呢?

    那中国除了公认的北上广深工作机会最多以外,还有那些城市也相对不错呢?

    这时候我们可能会打开招聘网站开始选择城市然后来了解这个城市的职位情况.

    那么一直秉持着人生苦短,我学python的我们,为什么不能用python来写一个分析2018全国各个城市的职位数排名的爬虫脚本呢?

    这么一想十分可行啊,我们只需要找到一个目标招聘平台,然后通过用代码get到它的html正文,通过BeautifulSoup分析html来得到我们想要的数据,然后用matplotlib画出图表就可以了. (完整代码见本文末尾.)

    于是立马动手,首先,既然我们是要分析全国范围内的所有城市的职位数,那么我们肯定首先要把所有的城市先列出来.然而这里想必地理学的再好的同学也不可能能把全国范围内所有的城市都能背下来吧,所以这一步,我们也是用python来爬取到全国范围内所有的城市名称.

    1.爬取全国范围内所有的城市列表

    通过一番查找,终于找到了智联上的这个页面.http://www.zhaopin.com/citymap.html

    乍一看好像所有的城市名都是加粗的,右键查看一下源代码,果然,所有的城市名都被加上了<strong>标签,类似于这样

    那就简单了,我们直接获取该网页所有<strong>标签里面的内容,就是标签名了.代码:

    def getCitys(citys):
        urlPath = "http://www.zhaopin.com/citymap.html"
        print("开始爬取所有城市:")
        r = requests.get(urlPath)
        if r.ok:
            r.raise_for_status()
            r.encoding = 'utf-8'
            data = r.text
            print("目标url:", urlPath)
            soup = BeautifulSoup(data, 'html.parser')
            a = soup.find_all('strong')
            for i in a:
                try:
                    citys.append(i.contents[0])
                except:
                    continue
        else:
            print("城市获取失败!")
    

    这样我们就获取到了所有的城市名,下一步我们就是要通过遍历这些城市名来查询某一个职业的职位数了.

    2.遍历城市名,爬取对应城市的职位数.

    这时候我们先打开智联的搜工作页面,输入职位名"android",地址选择"烟台",然后点击搜工作,这时候注意到,浏览器的地址栏变成了:

    http://sou.zhaopin.com/jobs/searchresult.ashx?jl=烟台&kw=android&p=1&isadv=0
    

    原来,智联的找工作这个按钮是执行了一个get请求而已,其中jl=和&kw=即分别代表要查找的城市和职位关键字,这时候先不要着急写代码,我们先来像上面说的一样来分析一下这个页面.
    首先第一眼直接就找到了这样的字眼

    上面赫然显示着共84个职位满足条件,一切总是那么完美,不需要多余的任何操作,仿佛传到桥头自然直一样,这不正是我们想要找的职位数吗.然后右键选择查看源代码.恩,不得不说相当完美!

    但这次数据格式好像比较复杂一点,我们如果仅仅简单用<em>84</em>标签包裹的内容来获取职位数的话好像已经行不通了,因为该网页很多的地方也使用了<em>标签,那怎么办呢,这时候我们只能使用正则表达式来匹配了.

    修修改改,最终的正则表达式是这样的:(?!共<em>)[0-9]+(?=</em>个职位满足条件),其中的?!和?=则是让其所在的括号内的内容不放入匹配缓冲区里.

    好,接下来我们就可以结合以上的内容来写代码了.

    import re
    import requests
    
    zhilianUrl = "http://sou.zhaopin.com/jobs/searchresult.ashx?jl=烟台&kw=android&p=1&isadv=0"
    r = requests.get(zhilianUrl)
    if r.ok:
        r.raise_for_status()
        r.encoding = 'utf-8'
        rr = r'(?!共<em>)[0-9]+(?=</em>个职位满足条件)'
        a = re.findall(rr, r.text, 0)
        print(a)
    else:
        print("职位数获取失败!")
    

    写完赶紧兴冲冲的run一下,...然而...

    结果是运行没有报错也没有任何输出,左边的红色方块显示程序还在运行中,是的,它卡住了,停止运行再重新start还是会卡主,检查一下程序也没问题啊,what?辛辛苦苦才到达了这步救过竟然卡住了?这个时候我们不要着急,身为一个整天跟各种BUG打交道的程序员,一定要镇定,努力分析问题可能的原因,然后解决问题.

    继续回到我们的这个问题上,排除我们程序本身的问题,会不会是对方的网站早知道我们会写python爬取,故意给我们加了限制呢?于是我们给我们的这次访问加上一个请求头试试,让我们的这次请求伪装成来自浏览器的访问.

    ok,改代码,给这次get请求加上一个请求头:

    import re
    import requests
    
    headers = {
        'Host': 'blog.csdn.net',
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
        'Accept-Encoding': 'gzip, deflate',
        'Referer': 'http://www.baidu.com',
        'Connection': 'keep-alive',
        'Cache-Control': 'max-age=0',
    }
    zhilianUrl = "http://sou.zhaopin.com/jobs/searchresult.ashx?jl=烟台&kw=android&p=1&isadv=0"
    r = requests.get(zhilianUrl, headers=headers)
    if r.ok:
        r.raise_for_status()
        r.encoding = 'utf-8'
        rr = r'(?!共<em>)[0-9]+(?=</em>个职位满足条件)'
        a = re.findall(rr, r.text, 0)
        print(a)
    else:
        print("城市获取失败!")
    
    

    运行:

    F:\PythonPoj\PythonLearn\venv\Scripts\python.exe F:/PythonPoj/PythonLearn/test.py
    ['84']
    
    Process finished with exit code 0
    
    

    果然这下就没问题了,程序瞬间就成功获取到了职位数为 84
    继续改动一下程序,遍历所有的城市列表,并根据key=城市名,value=职位数的格式将所有的城市职位数都获取来存到一个字典(Dictionary)里.

    def getData(citys, data):
        for city in citys:
            headers = {
                'Host': 'blog.csdn.net',
                'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0',
                'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
                'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
                'Accept-Encoding': 'gzip, deflate',
                'Referer': 'http://www.baidu.com',
                'Connection': 'keep-alive',
                'Cache-Control': 'max-age=0',
            }
            zhilianUrl = "http://sou.zhaopin.com/jobs/searchresult.ashx?jl=" + city + "&kw=" + zhiwei + "&p=1&isadv=0"
            r = requests.get(zhilianUrl, headers=headers)
            if r.ok:
                r.raise_for_status()
                r.encoding = 'utf-8'
                rr = r'(?!共<em>)[0-9]+(?=</em>个职位满足条件)'
                a = re.findall(rr, r.text, 0)
    
                if int(a[0]) >= 50 and hasCity(r):
                    print(city, zhiwei, a[0])
                    data[city] = int(a[0])
            else:
                print("城市获取失败!")
    

    这样我们就得到了这样的数据:
    {'北京': 4205, '上海': 2702, '广州': 1442, '深圳': 1872, '天津': 536 ...}

    使用matplotlib根据数据画出图表

    通过上面我们获取完了数据之后,直接用matplotlib库画出图表来就可以直观的看到各个城市的职位数情况了.

    def draw(keys, values):
        plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
        plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
        time = i = datetime.datetime.now()
        plt.title(str(time.year) + "/" + str(time.month) + "/" + str(time.day) + zhiwei + "职位数分布图")
        plt.bar(keys, values, label="职位数")
        plt.legend()
        plt.show()
    
    

    结果展示

    程序运行:

    运行结果:

    android爬取结果

    还可以修改一下脚本中的职位名,查找其他职业:

    python爬取结果 PHP爬取结果 会计爬取结果

    本文出自: http://www.jianshu.com/p/abe40b2919ed
    完整代码点此获取
    本文为作者原创,转载请注明出处.

    相关文章

      网友评论

        本文标题:利用python分析2018智联招聘全国各个城市的职位数排名

        本文链接:https://www.haomeiwen.com/subject/pydwoxtx.html