完美突破拉钩反爬

背景:拉钩网是一家专门提供互联网招聘的平台,反爬机制是做得很厉害的。在今年2到3月之间,做了一个比较具有迷惑性的反爬机制,导致网上99%以上的以往爬取拉钩信息的帖子都失效了。

本片帖子将详细一步步进行突破,并进行详细的分析。

环境:python3.6、time模块、json模块

工具:pycharm、Google Chrome

1、登录拉钩网,进行抓包分析。

本次爬取的是java相关的职位。在搜索栏输入java,然后搜索,在开发者工具中可以看到。第一个文件是HTML文件,它的名字更浏览器的输入框中出现的url的的一部分是完全相同的。HTML文档中没有我们需要的信息,我们需要的信息是以ajax异步的方式显示在网页中的。我们直接去看json文件。

完美突破拉钩反爬_第1张图片picture

2、可以看到里面有不少的json文件,但是真正有用的,只有下面这个文件,展开可以看到我们想啊哟ode信息正式包含在这个文件中。同时要注意一下开头是approve的那个文件,我们在点击下一页或者页码的时候,是想服务器发送了两个请求的,第一个是包含我们想要的数据的positionAjax开通的文件,另一个就是approve开通的这个东西。点开可以发现,approve文件里面凡是标true的数字,其实都是positionAjax中的companyId。而且approve其实是发送的get请求获取的。

完美突破拉钩反爬_第2张图片

但是当我们同时对这两个文件发送get请求和post请求的时候,发现还是不成功,说明我们的思路有问题。而且,请求approve的url是跟companyId有关,我们想要仿造进本是不可能的。

完美突破拉钩反爬_第3张图片

3、我们再仔细查看一下,发现一个有意思的地方,这些json文件的cookie都不一样。再结合headers里面所有的Referer都是https://www.lagou.com/jobs/list_java?city=%E6%AD%A6%E6%B1%89&cl=false&fromSearch=true&labelWords=&suginput=

跟我们最开始请求到的HTML文件url是一样的。我们大胆尝试一下先请求一下这个Referer,然后再发一个positionAjax的post请求,记得更新一下headers(这个很重要,是最近看到的一个大佬的帖子上提到的细节)。

这样尝试之后,我们会发现,果然,我们能拿到数据,我们突破了拉钩的坑了!真的不容易啊。

 

突破反爬之后,我们就可以批量获取数据了,我拿自己的code展示下。

import requests
import time
import json


url1 = "https://www.lagou.com/jobs/positionAjax.json?city=%E6%AD%A6%E6%B1%89&needAddtionalResult=false"
url2 ="https://www.lagou.com/jobs/list_java?city=%E6%AD%A6%E6%B1%89&cl=false&fromSearch=true&labelWords=&suginput="
headers = {
    "Referer": "https://www.lagou.com/jobs/list_java?city=%E6%AD%A6%E6%B1%89&cl=false&fromSearch=true&labelWords=&suginput=",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3642.0 Safari/537.36",
    "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
}


def get_page(url1, url2, headers,data,i):
    session = requests.Session()
    session.headers.update(headers)
    session.get(url2)
    info = session.post(url=url1, data=data)
    f = open("result%s.json" % i , "w", encoding="utf-8")
    json.dump(info.json(), f, ensure_ascii=False)


def run(url1, url2, headers):
    i = 1
    while True:
        try:
            data = {
                "first": "true",
                "pn": i,
                "kd": "java"
            }
            get_page(url1, url2, headers, data,i)
            time.sleep(3)
            i += 1
        except:
            print("出现问题")
            i += 1


if __name__ == '__main__':
    run(url1=url1, url2=url2, headers=headers)

需要注意的是,同一个ip如果爬取得信息次数过多,好像也会被封

 

你可能感兴趣的:(爬虫)