认证流程
浏览器清空cookies
步骤一
访问拉勾网网站 https://www.lagou.com/
做了些什么:
以get方式请求"https://www.lagou.com/"后,服务器在preview返回的信息包含了 X_Anti_Forge_Token,X_Anti_Forge_Code。
同时返回cookies,因为用requests.session(),所以cookies不考虑。
目标:拿到X_Anti_Forge_Token,X_Anti_Forge_Code。
应该对应的是不规则字符串,存疑!
步骤二
登录,先故意输错账户名,密码输对。获取其加密后的数据。拉勾网对密码进行了处理。
然后,将步骤一拿到的X_Anti_Forge_Token,X_Anti_Forge_Code,和用户名,密码 一起,往" https://passport.lagou.com/login/login.json "以post方式发送。
步骤三
以 get请求 往grant.html发送请求。
作用:获取授权。可能拉勾网比较特殊。
步骤四 验证
访问登录后的某个页面,response.text 拿到数据,判断页面上的某条数据在不在这response.text中。
补充:上述都是用requests.session()做到,所以过程中cookies 让requests模块帮我们处理了。
get,post请求中的User Agent,Referer,具体情况具体填写。
爬取职位信息流程
步骤一
页面进行筛选,url地址栏如果有汉字,真正访问的url会进行编码。条件会以 ?关键字=条件 追加在url末尾。
关键来了,然而,在浏览器返回给我们的数据中,和前端页面渲染的并不一致!竟然找不到!
原因何在?
服务器返回来的数据中会有ajax请求,浏览器会自动帮我们完成ajax请求,但是requests模块并不会!
so,在抓包中找到ajax,即XHR。
这里才是数据真正存放的地方!
在previes中查找到数据。
数据的格式是字典。
到这里,就可以循环遍历,拿到想要的数据了。
注意,在拉勾网上,positionID,很重要。
我们可以根据拉勾网,和positionID,拼接出相对应的工作在拉勾网上的站点。
为投简历这个最终目标最准备。
最后一步。投简历。
拿到相关工作的绝对路径后,刷出页面,不要忘了一步,需要拿到 X_Anti_Forge_Token,X_Anti_Forge_Code。
然后,当我们点击"投个简历"的时候,network会刷出一个 deliverResumeBeforce.json。
投简历实际上是往 deliverResumeBeforce.json 发了一个post请求。这就算投递成功。惊不惊喜。但需要data数据,和上一步拿到的X_Anti_Forge_Token,X_Anti_Forge_Code等。
补充:post请求,一般都会有data要发送。
get请求,post请求,在这里不出意外都需要referer,user_agent,不再多言。
感受到了吗,当点击 注册,投个简历,等需要用post方式访问网址,会与前一步get方式访问页面紧密相关。post方式,会用到get方式所返回的某些token,这些token是必不可少的。
回顾讲解时的反思:
grant.html,对其发送get请求,当response 里有location,requests模块自动跳转,不用管了。
后台会发的页面会包含ajax请求,requests不会识别。下载的页面并不含有想要的结果,那就有可能含有ajax请求。应该开心,因为会更方便。
用response.json()直接拿到字典格式的数据。套了好几层的字典。
so,去找浏览器的抓包,看抓到是ajax请求的包,XHR便是。
在这种情况下,请求的url是...Ajax.json,而不是地址栏中的list_python?city=北京...
关键是这个Ajax.json是怎么来的呢?
在我们原以为刷新list_python?...的情况下,response.text含有前端的所有信息,其实并不然。
在浏览器看到的,和response.text并不一样。so,我们考虑到 浏览器用ajax将一部分数据渲染出来。于是,去找ajax请求数据的网址,那里有我们
需要的网址数据。
附上原始代码,并不完全一样。
import requests import re # 1、============================================认证流程 session = requests.session() # 第一步: # 请求的URL:https://passport.lagou.com/login/login.html, # 请求的方法GET, # 请求头只包含User-agent r1 = session.get('https://passport.lagou.com/login/login.html', headers={ 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36', }, ) X_Anti_Forge_Token = re.findall("X_Anti_Forge_Token = '(.*?)'", r1.text, re.S)[0] X_Anti_Forge_Code = re.findall("X_Anti_Forge_Code = '(.*?)'", r1.text, re.S)[0] # print(X_Anti_Forge_Code) # print(X_Anti_Forge_Token) # 第二步: # 1、请求的URL:https://passport.lagou.com/login/login.json, # 2、请求方法POST, # 3、请求头: # Referer:https://passport.lagou.com/login/login.html # User-Agent: # X-Anit-Forge-Code # X-Anit-Forge-Token # X-Requested-With # 4、请求体: # isValidate:true # username:1111111111 # password:70621c64832c4d4d66a47be6150b4a8e #代表明文密码alex3714 session.post('https://passport.lagou.com/login/login.json', headers={ 'Referer': 'https://passport.lagou.com/login/login.html', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36', 'X-Anit-Forge-Code': X_Anti_Forge_Code, 'X-Anit-Forge-Token': X_Anti_Forge_Token, 'X-Requested-With': 'XMLHttpRequest' }, data={ 'isValidate': True, 'username': '18611453110', 'password': '70621c64832c4d4d66a47be6150b4a8e' } ) # 第三: # 1、请求的URL:https://passport.lagou.com/grantServiceTicket/grant.html, # 2、请求方法GET, # 3、请求头: # Referer:https://passport.lagou.com/login/login.html # User-Agent: session.get('https://passport.lagou.com/grantServiceTicket/grant.html', headers={ 'Referer': 'https://passport.lagou.com/login/login.html', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36', } ) # 验证 response = session.get('https://www.lagou.com/resume/myresume.html', headers={ 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36', } ) # print('18611453110' in response.text) # 2、============================================爬取职位信息 # 1、请求的url:https://www.lagou.com/jobs/positionAjax.json # 2、请求的方式:POST # 请求参数: # gj:3年及以下 # xl:不要求 # jd:不需要融资 # hy:移动互联网 # px:default # yx:15k-25k # city:全国 # 3、请求头: # User-Agent # Referer:https://www.lagou.com/jobs/list_%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD # X-Anit-Forge-Code:0 # X-Anit-Forge-Token:None # X-Requested-With:XMLHttpRequest # 4、请求体: # first:true # pn:1 # kd:python数据分析 from urllib.parse import urlencode params = {'kw': 'python数据分析'} res = urlencode(params).split('=')[-1] url = 'https://www.lagou.com/jobs/list_' + res # print(url) response = session.post('https://www.lagou.com/jobs/positionAjax.json', params={ # 'gj': '3年及以下', # 'xl': '不要求', # 'jd': '不需要融资', # 'hy': '移动互联网', 'px': 'default', 'yx': '15k-25k', 'city': '北京', 'district': '海淀区', }, headers={ 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36', 'Referer': url, }) # print(response.status_code) result = response.json()['content']['positionResult']['result'] for comanpy_info in result: fullname = comanpy_info['companyFullName'] emp_num = comanpy_info['companySize'] salary = comanpy_info['salary'] workyear = comanpy_info['workYear'] positionName = comanpy_info['positionName'] positionId = comanpy_info['positionId'] detail_url = 'https://www.lagou.com/jobs/%s.html' % (positionId) print(detail_url) print(fullname) print(emp_num) print(salary) print(workyear) print(positionName) print(positionId) print() # 3、============================================爬取职位信息 # 第一步:请求详情页: # 1、请求的detail_url:https://www.lagou.com/jobs/3984845.html # 2、请求的方式:GET # 3、请求头: # User-Agent r1 = session.get(detail_url, headers={ 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36', } ) X_Anti_Forge_Token = re.findall("X_Anti_Forge_Token = '(.*?)'", r1.text, re.S)[0] X_Anti_Forge_Code = re.findall("X_Anti_Forge_Code = '(.*?)'", r1.text, re.S)[0] # 第二步:投递简历 # 1、请求的url:https://www.lagou.com/mycenterDelay/deliverResumeBeforce.json # 2、请求的方式:POST # 3、请求头: # User-Agent # Referer:detail_url # X-Anit-Forge-Code:31832262 # X-Anit-Forge-Token:9ee8b4bc-7107-49a0-a205-cedd7e77c2d7 # X-Requested-With:XMLHttpRequest # 4、请求体: # 'positionId':3984845 # 'type':1 # 'force':True session.post('https://www.lagou.com/mycenterDelay/deliverResumeBeforce.json', headers={ 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36', 'Referer': detail_url, 'X-Anit-Forge-Code': X_Anti_Forge_Code, 'X-Anit-Forge-Token': X_Anti_Forge_Token, 'X-Requested-With': 'XMLHttpRequest' }, data={ 'positionId': positionId, 'type': 1, 'force': True } ) print('投递成功',detail_url)