使用BeautifulSoup爬取MCQ时自定义函数失效,无法将正确选项置于末尾
问题核心原因
- 自定义lambda抓取失效原因:BeautifulSoup解析class属性时,会将多类名自动拆分为字符串列表,你原代码中
tag.get('class') == ['radio-button-click-target correctquestions']的判断逻辑,是将包含单个拼接类名的列表,和实际包含两个独立类名的列表做等值比较,判断永远不成立,导致无内容抓取。 - 选项顺序不符合要求原因:原代码仅抓取带正确标识的选项,未单独提取普通选项做排序调整,自然无法实现正确选项置后的效果。
修正后实现逻辑
- 调整class匹配规则:改用
in操作符判断类名是否包含目标标识,兼容类名顺序变动的场景,同时避免无class属性的节点触发报错。 - 选项分类排序:每道题先提取所有普通选项,再单独分离出带
correctquestions标识的正确选项,最后按「普通选项在前、正确选项在后」的顺序输出。
可直接运行的修正代码
import requests from bs4 import BeautifulSoup address = 'https://www.ilmkidunya.com/online-test/5th-class-science-english-meduim-mcqs-with-answers?startfrom=0&last=92' response = requests.get(address) soup = BeautifulSoup(response.text, 'lxml') ques_id = soup.find_all('div', class_='q-title') ques_det = soup.find_all('div', class_='q-desc') optn_det = soup.find_all('div', class_='choose-answer-block') for i in range(0, len(ques_id)): print(ques_id[i].text) print(str(ques_det[i].text).strip()) # 抓取所有带radio-button-click-target标识的选项节点 all_opts = optn_det[i].find_all( lambda tag: tag.name == 'div' and 'radio-button-click-target' in tag.get('class', []) ) correct_opt = None normal_opts = [] # 分离正确选项和普通选项 for opt in all_opts: if 'correctquestions' in opt.get('class', []): correct_opt = opt else: normal_opts.append(opt) # 先输出普通选项,最后输出正确选项 for opn in normal_opts: print(str(opn.text).strip()) if correct_opt: print(str(correct_opt.text).strip()) print('<----->')
效果说明
- 自定义lambda判断逻辑调整后,可正常抓取所有选项节点。
- 自动完成选项分类排序,所有非正确选项按原页面顺序输出后,正确选项固定排在最后一位,符合要求。
内容的提问来源于stack exchange,提问作者ch_nerdy
相关产品推荐
相关产品推荐

