最近看到K-工作门户将公文标题按3个月的单位显示后,我产生了这样的想法。
如果通过爬虫将所有公文标题整理成3年期的Excel文件呢?
通过filter可以轻松搜索公文编号。
我先下结论,不可能。

1. 每个人都有计划。
我的宏伟计划是这样的。
1. 使用 python 的 selenium 访问工作门户并登录。
2. 使用 xpath 收集 table 标签内部的 tr 和 td,并将其制成数据帧。
3. 使用 datetime 和 delta 计算日期,将公文按3个月单位收集齐全。
4. 使用 Excel 或 Google 表格合理利用。但是实际进入工作门户时,连 table 都找不到,iframe更是找不到。
折腾了4小时后,我记录下爬虫不可能的原因。
2. 你的安全在哪里?
1. WebDRM

第一个障碍是 WebDRM。
这导致无法开启开发者模式。
不过利用开发者模式已经开启的情况下,即使访问该网站也能保持的方法,成功开启了开发者模式。
2. 浏览器可见但没有元素?
这部分最难以理解。
明明开发者模式下元素清晰可见,但在 Chrome 驱动中执行 page_source 时没有任何元素。
无论使用 selenium 还是 puppeteer,结果都是一样。
更神奇的是,即使在控制台使用 JavaScript 也看不到。
看得到却找不到,这种似是而非的情况让我更加发疯。
const puppeteer = require('puppeteer');
const fs = require('fs');
// 使用 puppeteer 获取网页 HTML 的脚本
(async () => {
let browser;
try {
browser = await puppeteer.launch({
headless: false,
args: ['--no-sandbox', '--disable-setuid-sandbox'],
defaultViewport: null,
userDataDir: './user_data',
});
const page = await browser.newPage();
await page.goto('https://klef.goe.go.kr/keris_ui/main.do', {
waitUntil: 'networkidle0', // 等待所有资源加载
timeout: 60000, // 最长等待60秒
});
const html = await page.content();
fs.writeFileSync('schoolDoc.html', html, 'utf8');
console.log('HTML 文件已保存为 schoolDoc.html。');
} catch (error) {
console.error('发生错误:', error);
} finally {
if (browser) await browser.close();
}
})();这样保存的文件再次打开时显示如下。
想要的表格没有出现,登录模块倒是弹出来了。

思考为什么会这样,觉得公文显示的表格本身可能并不是其他安装类型的程序。
这样想来放弃就容易多了。
3. 工作门户使用 WebSocket。
首先,工作门户不是通过常规的 REST API 传送数据,而是使用 websocket 与用户进行数据交换。
这一点非常有趣。

因此,即使尝试使用 requests 等库复制 cookie 进行新连接,因 websocket 的握手过程和会话保持方式,仍然无法实现。
但我不愿在此放弃。
于是决定通过 selenium-wire 查看通过 websocket 进行的请求和响应。
# 循环请求
for request in driver.requests:
if request.response:
content_type = request.response.headers.get('Content-Type', '')
if content_type.startswith('application/json'):
print("== 请求 URL:", request.url)
try:
body = request.response.body.decode('utf-8', errors='ignore')
print("== 响应内容:", body)
except Exception as e:
print("== 解码错误:", e)
driver.quit()结果得到似乎是 base64 编码的字母。
尝试解码,但因不符合规范而失败。
到此我决定停下来。
3. 感想
对公共机构网站的速度缓慢不满,但这次尝试后觉得至少安全做得很好。
获得远程数据并不容易,通过此经历学到了不少。
不过,下次可能还会再试。

댓글을 불러오는 중...