Python 爬虫实战:统计杭电 OJ 题目 AC 率并排序
本文介绍如何利用 Python 的 urllib 和 BeautifulSoup4 库,编写爬虫程序抓取杭电 OJ 多页题目数据。通过解析网页 DOM 结构,提取题号、名称、AC 数与提交次数,计算正确率并排序,最终将结果保存至本地文本文件。
核心工具与原理
实现该爬虫主要依赖两个 Python 库:urllib 和 BeautifulSoup4。urllib 是 Python 内置的 HTTP 请求库,包含 request、error、parse 和 robotparser 四个模块。其中 request 用于模拟发送 HTTP 请求,error 处理请求异常,parse 提供 URL 解析功能,robotparser 用于识别 robots.txt 文件。在本示例中,仅使用了 request 模块进行数据抓取。BeautifulSoup4 从 bs4 包中导出,主要用于解析网页 HTML 结构,将复杂的 DOM 树转换为易于操作的 Python 对象。
数据抓取与解析流程
杭电 OJ 的题目列表分布在多页中,程序通过循环遍历页码(1 至 58 页)来抓取所有数据。具体步骤如下:
- 构造请求 URL:根据页码生成目标网址,例如
http://acm.hdu.edu.cn/listproblem.php?vol=页码。 - 获取网页内容:使用
urllib.request.urlopen()打开 URL 并读取 HTML 内容。 - 解析 DOM 结构:将读取的 HTML 内容传入
BeautifulSoup,指定解析器为html.parser。通过链式调用.body.table.contents[11].td.table.contents[1]定位到包含题目列表的特定 DOM 节点。 - 提取原始数据:将定位到的节点内容转换为字符串,截取特定部分(去除前后固定字符)后,以分号
;为分隔符拆分为列表,得到所有题目的原始字符串。
数据清洗与存储
获取题目列表后,需对每个题目字符串进行格式化处理,提取关键信息并存入字典。处理逻辑如下:
- 使用
split()方法依次分割字符串,提取题号(num)、题目名称(name)、AC 次数(right)和提交次数(submit)。 - 对数值型数据进行类型转换,并计算正确率(
AC 次数 / 提交次数)。 - 将处理后的数据以列表形式存入字典,键为题目编号,值为包含名称、AC 数、提交数和正确率的列表。
排序与结果保存
所有页面数据抓取并处理后,利用 sorted() 函数对字典项进行排序。排序规则为按正确率(列表索引 3 的位置)升序排列。最后,将排序后的结果写入本地文本文件 Statistics.txt,每行存储一个题目的统计信息。
#杭电OJ题目AC率排序
import urllib.request as ur
from bs4 import BeautifulSoup
dic = {} #存:"题号:题名 AC 提交次数 正确率"
for t in range(1,59,1):#1~58页都爬一遍
print(t)
url = 'http://acm.hdu.edu.cn/listproblem.php?vol='+str(t) #存网址
bs = BeautifulSoup(ur.urlopen(url).read(),"html.parser")#获取网址的html并转换为可以python可以使用的结构
ql0 = str(bs.body.table.contents[11].td.table.contents[1])#网页的DOM解析后可以直接通过"."来寻找子元素,找到题目的列表元素后,将列表中所有题目转换成字符串。(可以输出看看)
ql = ql0[30:-10].split(";") #字符串中的题目以";"分隔,将它们分开,并存到列表中
for i in ql: #以下就是格式化处理每个题目,然后存到字典中
info1 = i.split(',"',1)
num = info1[0].split(',')[1]
info2 = info1[1].split('",',1)
name = info2[0]
right,submit = info2[1].split(',',1)
submit = submit[:-1]
dic[num] = [name,int(right),int(submit),int(right)/int(submit)]
dic = sorted(dic.items(),key = lambda x: x[1][3]) #每页题目都存入字典后,把字典中的题目通过正确率进行排序,传出列表
with open('Statistics.txt','w',encoding = 'utf-8') as f:#把统计排序好的题目保存到txt中
for i in dic:
f.write(str(i)+'\n')
print("Success!")以上就是 Python 爬虫基本使用——统计杭电 OJ 题目正确率并排序的详细内容,更多关于 Python 爬虫、urllib 和 BeautifulSoup4 的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













