猿人学 — 第1届第4题(解题思路附源码)
猿人学 — 第1届第4题
-
分析:由响应数据和页面的
html
可知style
属性中display
为none
的img
标签在页面上并不显示,为干扰项html
中img
标签的相对顺序不与页面上的数字相对顺序对应
-
问题1:如何排除干扰项;问题2:如何还原正确的顺序
-
解决问题1:返回的
info
中,所有img
标签并没有style
属性,并且class
属性中有一串奇怪的字符;并且请求返回的数据中有key,value,iv
貌似还没用到,因此进入js源码中查看
-
success:可以看到请求成功后,执行了一段代码。大概意思是,若一个标签的
class
属性中含有j_key
字符串内容,则为这个标签添加上display:none
,即不显示。对比返回结果和页面数据显示,发现确实如此,因此可扣下相关的代码
-
解决问题2:可以发现,若
left:0
,则相对初始位置没有移动;若left:11.5
,则代表其相对初始位置向左移动了一个单位;若left:-11.5
,则代表其相对初始位置上向右移动了一个单位;并且观察其它的,可发现11.5px
为一个基本单位。因此我们在后续的逻辑中,就可以提取img
标签style
属性中的left
值,从而定位它们的初始位置 -
源码如下:
import re import execjs import base64 import ddddocr import requests import multiprocessing # 读入并编译js代码用于生成特征信息 with open('v1.js', 'rt', encoding='utf-8') as f: JS_STRING = f.read() JS_CODE = execjs.compile(JS_STRING) # 实例化一个DddOcr对象用于识别图片 OCR = ddddocr.DdddOcr(show_ad=False) # 请求page页获取响应信息 def get_data(page): """ 请求page页获取响应信息 """ res = requests.get( url=f'https://match.yuanrenxue.cn/api/match/4?page={page}', headers={ 'Referer': 'https://match.yuanrenxue.cn/match/4', # 用你自己的Cookie 'Cookie': 'Hm_lvt_c99546cf032aaa5a679230de9a95c7db=1728951512; HMACCOUNT=11F164A33FD6330D; qpfccr=true; no-alert3=true; tk=8258780053392544352; sessionid=9eqltqfxxrf7u6emsd3lajycdae9yg24; Hm_lvt_9bcbda9cbf86757998a2339a0437208e=1728951539; Hm_lpvt_9bcbda9cbf86757998a2339a0437208e=1728961624; Hm_lpvt_c99546cf032aaa5a679230de9a95c7db=1728961660' } ) if res.status_code != requests.codes.ok: print(f"{page}页数据获取失败") key = res.json()['key'] value = res.json()['value'] info = res.json()['info'] return key, value, info def display_no(key, value): """ 根据请求中返回的key和value调用js代码生成特征信息 若这个特征信息存在于img标签中,则该img标签的dispaly为none即不显示 """ display_no_string = JS_CODE.call('display_no', key, value) return display_no_string def handle_info(info, display_no_string): """ 根据info和不显示的img标签的特征信息,提取、筛选、排序和识别图片,返回info所在页的数字和 :param info: 请求page页返回的响应中键info对应的值 :param display_no_string: 如果在一个img标签中被包含,则说明这个img将不显示 """ page_total_value = 0 # 每页中有多少个数据即包含多少个td标签 td_list = re.findall('<td>.*?</td>', info) for i in range(len(td_list)): # 提取一个td标签中的所有img标签 img_list = re.findall('<img.*?>', td_list[i]) # 根据特征信息删除不显示的img标签 img_list = [x for x in img_list if display_no_string not in x] # 根据style属性中的left值对这几个img标签进行重新排序 sort_img_list = [0] * len(img_list) for j in range(len(img_list)): img_string = img_list[j] # 提取img标签中style属性的left值,并计算出其初始位置的下标 left = float(re.findall('left:(.*?)px', img_string)[0].strip()) position = j + int(left // 11.5) # 只将img标签中的bas464编码信息存入最终的结果列表 sort_img_list[position] = re.findall('base64,(.*?)"', img_string)[0] # 利用ddddocr识别图片 single_value = '' for j in range(len(sort_img_list)): body = base64.b64decode(sort_img_list[j]) code = str(OCR.classification(body)) single_value += code page_total_value += int(single_value) # print(single_value,end=' ') return page_total_value def worker(page): try: key, value, info = get_data(page) display_no_string = display_no(key, value) page_total_value = handle_info(info, display_no_string) return page_total_value except Exception as e: return f'Error:{e}' # print(f"第{page}页计算结束") if __name__ == '__main__': # 多进程执行 with multiprocessing.Pool(processes=5) as pool: results = pool.map(worker, range(1, 6)) total_value = sum(results) print(f"求和:{total_value}")
-
运行结果:
-
结语:若上述分析和代码有错误、不合理或值得优化的地方,欢迎各位大佬批评指正,不吝赐教!
原文地址:https://blog.csdn.net/Learner_HJ/article/details/142965055
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!