美文网首页
爬虫-(旧)BOSS直聘数据分析相关职位数据

爬虫-(旧)BOSS直聘数据分析相关职位数据

作者: 花讽院_和狆 | 来源:发表于2020-03-12 10:26 被阅读0次

    最近学习数据分析,因此尝试一下这两个网站的职位需求做分析用,在其中遇到了很多坑,记录一下。

    框架就选用了scrapy,比较简单,建了两个文件,分别作用于不同的网站。

    image

    先来看BOSS直聘:

    网上搜了很多BOSS直聘的例子,以为很容易,只需要模拟一个登陆头就可以了……但是进去发现完全不是那么一回事。

    按照惯例,首先在items.py中定义需要获取的数据:

    import scrapy
    
    
    class PositionViewItem(scrapy.Item):
        # define the fields for your item here like:
        
        name :scrapy.Field = scrapy.Field()#名称
        salary :scrapy.Field = scrapy.Field()#薪资
        education :scrapy.Field = scrapy.Field()#学历
        experience :scrapy.Field = scrapy.Field()#经验
        jobjd :scrapy.Field = scrapy.Field()#工作ID
        district :scrapy.Field = scrapy.Field()#地区
        category :scrapy.Field = scrapy.Field()#行业分类
        scale :scrapy.Field = scrapy.Field()#规模
        corporation :scrapy.Field = scrapy.Field()#公司名称
        url :scrapy.Field = scrapy.Field()#职位URL
        createtime :scrapy.Field = scrapy.Field()#发布时间
        posistiondemand :scrapy.Field = scrapy.Field()#岗位职责
        cortype :scrapy.Field = scrapy.Field()#公司性质
    

    上面定义的就是ITEM,构思好需要的数值,目前就简单的设置为普通的scrapy.Field()

        name :str = 'DA'
        url :str='https://www.zhipin.com/c100010000/?query=%E6%95%B0%E6%8D%AE&page=10'#起始url设定为进入BOSS直聘之后的搜索页,搜索参数为全国的数据分析
        cookies :Dict = {
            "__zp_stoken__":"bf79ElaZ4z7IK5JruWAX5j256l7CJf3k7Ag2A9mrsSPN%2FnLgjChK0LguCrB%2FtIEFMKdnysNhr4ilqIicjeHkCsCpBQ%3D%3D"
        }#设置cookies
        headers :Dict = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0',
            'Referer': 'https://www.zhipin.com/web/common/security-check.html?seed=6gkgYHovIokVntQcwXUH9KW3%2FbEZsqfeaoCctIp1rE8%3D&name=f2d51032&ts=1571623520634&callbackUrl=%2Fjob_detail%2F%3Fquery%3D%25E6%2595%25B0%25E6%258D%25AE%25E5%2588%2586%25E6%259E%2590%26city%3D100010000%26industry%3D%26position%3D&srcReferer=https%3A%2F%2Fwww.zhipin.com%2Fjob_detail%2F%3Fquery%3D%25E6%2595%25B0%25E6%258D%25AE%25E5%2588%2586%25E6%259E%2590%26city%3D100010000%26industry%3D%26position%3D'
        }#设置登录头
    
    

    设置完常用的参数之后,尝试定义start_requests方法作为爬取的起始url

        def start_requests(self) -> Request:
            
            yield Request(self.url, headers=self.headers, cookies=self.cookies)#返回一个yield,调用默认callback,第一个参数是之前定义的url,第二个是定义的请求头,第三个是cookies。
    

    scrapy中默认的回调函数为parse,直接定义一个parse用于获取response的内容,之后直接用xpath语法进行解析。

        def parse(self, response) -> None:
            if response.status == 200:
                PositionInfos :selector.SelectorList = response.selector.xpath(r'//div[@class="job-primary"]')
                for positioninfo in PositionInfos:
                    pvi = PositionViewItem()
                    pvi['name'] = ''.join(positioninfo.xpath(r'div[@class="info-primary"]/h3[@class="name"]/a/div[@class="job-title"]/text()').extract())
                    pvi['salary'] = ''.join(positioninfo.xpath(r'div[@class="info-primary"]/h3[@class="name"]/a/span[@class="red"]/text()').extract())
                    pvi['education'] = ''.join(positioninfo.xpath(r'div[@class="info-primary"]/p/text()').extract()[2])
                    pvi['experience'] = ''.join(positioninfo.xpath(r'div[@class="info-primary"]/p/text()').extract()[1])
                    pvi['district'] = ''.join(positioninfo.xpath(r'div[@class="info-primary"]/p/text()').extract()[0])
                    pvi['corporation'] = ''.join(positioninfo.xpath(r'div[@class="info-company"]/div[@class="company-text"]/h3[@class="name"]/a/text()').extract())
                    pvi['category'] = ''.join(positioninfo.xpath(r'div[@class="info-company"]/div[@class="company-text"]/p/text()').extract()[0])
                    try:
                        pvi['scale'] = ''.join(positioninfo.xpath(r'div[@class="info-company"]/div[@class="company-text"]/p/text()').extract()[2])
                    except IndexError:
                        pvi['scale'] = ''.join(positioninfo.xpath(r'div[@class="info-company"]/div[@class="company-text"]/p/text()').extract()[1])
                    pvi['url'] = ''.join(positioninfo.xpath(r'div[@class="info-primary"]/h3[@class="name"]/a/@href').extract())
                    yield pvi
                nexturl = response.selector.xpath(r'//a[@ka="page-next"]/@href').extract()
                if nexturl:
                    nexturl = urljoin(self.url, ''.join(nexturl))
                    print(nexturl)
                    yield Request(nexturl, headers=self.headers, cookies=self.cookies, callback=self.parse)
    

    xpath选择器后面跟的.extract()会返回一个list,里面包含的是选择器选择出来的所有元素,如果选择不出来,那么这个语句会报错而不是返回空值!

    yield pvi的作用是把定义好的ITEM传给pipelines,方便在pipelines中对获取的数据进行操作。

    nexturl = response.selector.xpath(r'//a[@ka="page-next"]/@href').extract()获取到下一页的链接之后,要用urllib.parse中的urljoin将获取到的链接和源链接进行合并,因为抓到的链接并不是一个完整的url,而是类似于

    /c101010100/?query=%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90&page=2这种格式,需要用urljoin进行合并,合并规则如下:

    url='http://ip/ path='api/user/login' urljoin(url,path)拼接后的路径为'http//ip/api/user/login'

    本以为这样就好了,用scrapy crawl + 名字()运行,结果发现请求不到数据,会直接302重定向到一个securitycheck的网页.

    打开fiddler查看请求过程:

    image

    可以看到完全模拟了整个查询过程,先直接请求一遍地址,之后重定向到security-check的网页,之后再切回到返回的页面,看上去没有问题,但是仔细查看会发现cookies中的__zp_token__发生了变化:

    image image image

    那么就很清楚了,应该是在调用security-check之后回写了一个token,之后根据这个最新的token来判断请求,看了一下似乎是通过一个js进行加密回写的,知乎上有大神写了解密的办法,对前端不太懂,放弃了...

    转载链接如下:https://zhuanlan.zhihu.com/p/83235220

    这个token只能通过手动刷新的方式获取,一般能持续个几次请求就会失效,要重新获取.不过手动爬也只能爬个10页左右,后面的不登陆就没有了,因此也无所谓.

    后来尝试通过selenium模拟的方式进行,也宣告失败.

    总之不是很成功,目前不推荐啦...

    相关文章

      网友评论

          本文标题:爬虫-(旧)BOSS直聘数据分析相关职位数据

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