开头碎碎念,上一篇写文还是两年多以前了,工作浑浑噩噩摆了两年,最近朋友在找工作,工作空闲之余我也看了一下猿人学的题,正好验证一下工作两年的成果,我从简单的开始做起,没想到啊一开始就给我卡住了,下面开始讲一下我的做题过程吧
题目
解题思路
看起来是不是特别简单,实际上也是特别简单,但是我就是卡了好一会。
首先打开开发者工具,点击第二页后可以看到,这次点击发出了两次请求,如下图:
我们点击第一个请求,可以看到返回了一串js,如下图:
把这段js拿去执行会得到:
"yuanrenxue_cookie=1792046210|7BNT28COtfBiBhDQFX4plSYMLyw2jFUTMABk80wR5UJ1vgif0C49X4ru3wTaJaXcI4ddbBycIiEvTFFzRPZiku2dKjTt2b5zWqqZiPyVaROW2q4lClJoHmh4QJHYZKI8rNVr4KrGTuBcZRPLi;path=/"
这很明显就是cookie内的一个值。果然点击第二个请求就可以看到,这次请求的cookie里面就有这个值
于是我们再点击第三页,可以看到还是发起了两次请求,第三页的第一次请求(得到cookie)里面的cookie值和我们第二页的第一次请求返回的js执行得到的cookie值是一致的(这里是个坑),所以思路也就很明确了,把前一页第一次请求得到的cookie用在后续请求数据和下一页得到cookie的请求中,然后重复五次,拿到所有数字求和即可解题。
敲代码过程
这里是得到cookie值并处理,然后调用js环境来得到后续请求用来的cookie值
response_cookies = requests.get('https://match.yuanrenxue.cn/api2/13', headers=headers) print(response_cookies.text) final_cookie = response_cookies.text[len("document.cookie="):].rstrip(";") ctx = execjs.compile("function get_cookie() { return %s; }" % final_cookie) cookie_value = ctx.call("get_cookie")然后我们把这次请求得到的值拿到后续请求中
params = { 'page': '1', 'pageSize': '10', 'kw': '' } response = session.get('https://match.yuanrenxue.cn/api/question/13', params=params, cookies=cookies, headers=headers) data_list = response.json()['data']然后我就发现,一直响应400,请求没有通过,给的提示是'token failed'
我就一直以为是我上面处理js部分处理的不对,死磕了好久。然后我突然灵光乍现,是不是两次请求要用一个request,之后我就用session来请求cookie之后再请求数据,发现通过了。最后也很轻松得到了五页数字求和的结果。但是得到的求和结果始终不对,我自己手动翻页计算发现确实对不上,而且是每一页的数据都对不上。经过长时间的思考后我又猛地发现我的第一次请求是没有带cookie的,因为之前的思路是把前一页第一次请求得到的cookie用在后续请求数据和下一页得到cookie的请求中,所以我就想当然地以为在第一页的第一次请求中不用带cookie,后续四页带上就行。
最后在这里把cookie加上后,再次运行代码,得到的结果就正确了,经过测试cookie内只带sessionid就可以通过验证。我还测试了不用session来请求,两次分别request也是能得到最终结果的,这里我就只给用了session的代码。
完整代码
import requests import time import execjs session = requests.Session() cookies = { 'Hm_lvt_434c501fe98c1a8ec74b813751d4e3e3': '1788832813', 'sessionid': '带上你的sessionid', 'Hm_lvt_f80b2b389f44bbfb3bfe1704817d44e0': '1790730910,1791431799,1791949822', 'HMACCOUNT': '30D74844B380FA1E', 'Hm_lpvt_f80b2b389f44bbfb3bfe1704817d44e0': '1792033114' } headers = { 'accept': 'application/json, text/javascript, */*; q=0.01', 'accept-language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,ja;q=0.6', 'priority': 'u=1, i', 'referer': 'https://match.yuanrenxue.cn/match/13', 'sec-ch-ua': '"Chromium";v="154", "Google Chrome";v="154", "Not A(Brand";v="99"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': '"Windows"', 'sec-fetch-dest': 'empty', 'sec-fetch-mode': 'cors', 'sec-fetch-site': 'same-origin', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/154.0.0.0 Safari/537.36', 'x-requested-with': 'XMLHttpRequest' } def get_cookie(): response_cookies = session.get('https://match.yuanrenxue.cn/api2/13', headers=headers, cookies=cookies) clean_cookie = response_cookies.text[len("document.cookie="):].rstrip(";") ctx = execjs.compile("function get_cookie() { return %s; }" % clean_cookie ) cookie_value = ctx.call("get_cookie") return cookie_value count = 0 for i in range(1, 6): cookies["yuanrenxue_cookie"] = get_cookie().replace(";path=/", "").replace("yuanrenxue_cookie=", "") session.cookies.set("yuanrenxue_cookie", cookies["yuanrenxue_cookie"]) params = { 'page': str(i), 'pageSize': '10', 'kw': '' } if i == 5: headers['user-agent'] = "yuanrenxue" session.headers.update(headers) response = session.get('https://match.yuanrenxue.cn/api/question/13', params=params, cookies=cookies, headers=headers) data_list = response.json()['data'] count += sum([item for item in data_list]) time.sleep(1) print(count)结语
看来我的基础还是不太牢靠,确实在我工作中很少用到session来请求,学习之路,任重而道远啊