python抓取信息学奥赛一本通OJ题库
发布网友
发布时间:2024-10-19 04:28
我来回答
共1个回答
热心网友
时间:2024-11-24 11:38
〇、前言
有一个搭建OJ平台的想法,未来可能在学校使用。为了实现这一目标,作者正在逐步学习所需知识。目前,OJ平台需要题库,因此计划先从现有的OJ平台上抓取题目数据,以方便实验。
需要注意的是,目前只能获取到题目信息,测试点数据还需自行创建。
作者学习Python和爬虫已有段时间,因此打算使用Python编写一个小爬虫来抓取题库。
选择了大学课程中老师推荐的信息学奥赛一本通(C++)版在线测评网站,原因之一是该网站设计简单,数据易于获取。
一、踩点
该网站界面简洁,无需登录即可查看题目。URL中传递的“pid=”后面的数字代表题目编号,从1000开始。
需要抓取的数据包括:题目编号、题目名称、题目描述、输入、输出、输入样例、输出样例、提示(部分题目包含此内容)。
需要特别注意的几点:
1.可能会有图片。
2.部分题目包含“提示”内容。
F12查看需要的数据部分,发现其结构不太规范,包含关系较为混乱。
二、抓取数据
使用requests.get方法抓取网站数据。
复制题目URL,设置一个合理的pid参数,通过循环可以抓取所有题目。同时,构造headers模拟浏览器行为。
三、数据整理
使用lxml库处理抓取到的网页数据。
利用xpath查找所需数据
例如,查找题目名称
但后续数据处理较为复杂,小标题位于
标签中,内容文字在标签中,两者并列而非包含关系。例如,pid=1000的例子中,输入样例的数据、输出样例的标题和数据位于下一层包含中。
因此,我们只能将可能存在的标签位置全部抓取下来,然后根据小标题文字内容进行整理。
例如,“题目描述”之后的内容为题目描述的文字部分,直到出现“输入”。
代码如下
用一个tyb作为标记,指示当前读取的是哪一块内容。
如果读取到图片,则保存图片,并在文本位置添加“图片+图片序号”作为标记,方便后期处理。
如果是文字,则将其添加到相应的字符串中。
当读取到“来源”时,表示前面的内容已经处理完毕,而作者不需要记录来源信息,因此直接结束。
四、效果
五、保存数据
上一步已经成功按照内容类别将所需数据记录到各自的字符串中,保存数据变得非常容易。可以将数据打印输出或保存到数据库,作者这里选择将其保存到Excel中。
五、完整代码