(说明:此办法只适用于 P 系列题目。且本文章追求的是代码简单而不是效率高。)
(若本篇文章有哪些不当之处,请各位大佬不吝批评、指正。)
2018.2 更新:现在洛谷已经公开所有算法标签,有更简单的获取方法。但是此文爬虫稍作一行修改即可统计算法频率。
1. 观察算法标签的特点
首先,进入洛谷的题目列表,并单击右侧的「显示所有算法标签」按钮,显示出每道题目的算法标签。通过观察,我们不难发现,所有的算法标签都是粉色的(如图)。
我们再审查一下算法标签元素,发现每一个算法标签的元素都属于一个相同的 class: class="lg-tag am-badge am-radius lg-bg-pink"。(如图)。
为了解决翻页问题,可以直接在 URL 末端加上?page=n表示题目列表的第几页。
2. 思考爬虫实现方法
因为洛谷的题目列表不用登录账户就能查看,所以不需要 post 请求,也不需要处理 cookie,只要 get 就行了。所以,可以使用 requests 库中的 get。但是如果使用 requests,还需要配合其他的库(如 BeautifulSoup)来解析信息,有点麻烦。所以在这里我选择使用可视化的 Selenium 库。
为什么选择 Selenium 呢?因为 Selenium 有一系列很强大的函数:find_element(s)_by_*()。使用这一系列函数可以很轻松的获取到一个(或多个)符合条件的元素信息。因为我们将根据元素的 class 寻找元素,所以可以使用 find_elements_by_class_name()。函数参数填写一个字符串表示元素的 class,函数返回一个列表,其中包含了所有符合条件的元素信息。遍历这个列表,输出列表中每个元素的 text,即为元素在网页中显示的文字。
因为有一些算法非常常用(如动态规划),会重复很多次,所以我们定义一个列表作为算法标签的集合。每遇到一个标签,判断是否已经在列表中。若不在,则添加进去;若在,则跳过这个标签。
3. 编写代码
0x00: 引入需要的库:
from selenium import webdriver
0x01: 定义并初始化一些要用到的变量 / 对象:
urlBase = 'https://www.luogu.org/problem/lists?&page='
maxPage = 61 # 总共有 61 页题目(截止到写这篇文章)
tags = [] # 算法标签集合
wd = webdriver.Firefox() # 借助 Firefox 浏览器完成爬虫工作
0x02: 编写核心代码
for i in range(1, maxPage + 1):
wd.get(urlBase + str(i)) # 到指定的页码去
wd.find_element_by_xpath('/html/body/div[1]/div[2]/div[2]/div[1]/section/p[1]/button[3]').click() # 模拟单击「显示所有算法标签」按钮
elements = wd.find_elements_by_class_name('lg-tag.am-badge.am-radius.lg-bg-pink') # 寻找当前页面所有算法标签,保存在一个临时的列表里
for element in elements:
if element.text not in tags: # 判重
tags.append(element.text)
0x03: 输出结果
for tag in tags:
print tag
4. 运行爬虫(完)
字符串 模拟 动态规划,动规,dp 高精 枚举,暴力 费用流 递归 进制 贪心 数论,数学 分治 斐波那契,Fibonacci 排序 搜索 二分答案 剪枝 递推 图论 计算几何 最大公约数,gcd 树形结构 深度优先搜索,DFS 概率论,统计 广度优先搜索,BFS 素数判断,质数,筛法 拓扑排序 前缀和 卡特兰,Catalan 栈 离散化 线段树 背包 SPFA 位运算,按位 最短路 倍增 扩展欧几里德,扩欧 构造 二叉堆 优先队列 单调队列 快速排序,快排 哈希,HASH 选择排序 Splay 平衡树 并查集 线性结构 冒泡排序 归并排序 后缀数组,SA 生成树 割点 队列 二分图 匈牙利算法 最大匹配 树形动规 桶排 排列组合 二分查找 树状数组 线性递推,递推式 迭代加深 连通块 博弈论 st表,稀疏表 Prim 向量 矩阵乘法 网络流 差分约束 强连通分量,缩点 邻接矩阵 邻接表 记忆化搜索 极限 堆排序 模拟退火 矩阵运算 插入排序 欧拉回路 最大流 最小割 最近公共祖先,LCA 叉积 骗分 随机贪心,随机化 众数 zkw线段树 RMQ 置换 逆元 容斥 凸包 环套树 左偏树 同余,中国剩余定理 Link-Cut Tree,LCT 级数 组合数学 降低维度,降维 斜率优化 状态压缩,状压 负权环 Floyd 二维线段树 期望 Treap 区间动规,区间dp 四边形不等式 块状链表,块状数组 莫队 快速傅里叶变换,DFT,FFT 图的建立,建图 高斯消元 树链剖分,树剖 哈夫曼,Huffman 哈夫曼树 树的直径 Kruskal SBT 数位动规,数位dp AC自动机 字典树,Trie树 Tarjan A\*算法 启发式搜索 KMP 虚树 主席树 斜堆 AOE K短路 动态树 莫比乌斯反演 康托展开 Nim游戏 半平面相交,半平面交 树套树 可持久化 点分治 Sap 异或方程组 矩阵加速,矩阵优化 集合论 仙人掌 旋转卡壳 NP问题 分数规划 2-SAT 线性基 积分 线性代数 Dijkstra 遗传 生成函数 K-D Tree 后缀自动机,SAM