crawlee/misc/test_expand_grafana_v15.js
2025-04-23 12:14:50 +08:00

161 lines
6.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const { chromium } = require('playwright');
const fs = require('fs');
const path = require('path');
(async () => {
// 启动浏览器
const browser = await chromium.launch({
headless: true // 设置为有头模式,方便观察
});
const context = await browser.newContext();
const page = await context.newPage();
try {
page.setViewportSize({ width: 2560, height: 1440 });
// url = "https://play.grafana.org/a/grafana-app-observability-app"
url = "https://play.grafana.org/dashboards"
// url = "https://play.grafana.org/a/grafana-synthetic-monitoring-app/probes"
// 访问目标网站,增加超时时间并添加重试逻辑
console.log(`正在访问 ${url}...`);
// 增加超时时间到 120 秒
await page.goto(url, {
timeout: 120000, // 增加到 120 秒
waitUntil: 'domcontentloaded' // 改为只等待 DOM 加载完成,不等待所有资源
});
console.log('页面加载完成');
// 等待页面稳定
try {
await page.waitForLoadState('networkidle', { timeout: 30000 });
} catch (e) {
console.log('网络未完全空闲,但继续执行:', e.message);
}
// 展开所有折叠的部分
console.log('\n开始展开导航项...');
// 用 Set 来记录已经点击过的按钮
const clickedButtons = new Set();
const expandButtons = async () => {
console.log('开始寻找可展开按钮...');
// 查找所有折叠按钮
const buttons = await page.$$('button[aria-label*="Expand"], button[aria-label*="Open"], button[aria-expanded="false"]');
console.log(`找到 ${buttons.length} 个折叠按钮`);
let newButtonsFound = false;
for (const button of buttons) {
try {
const ariaLabel = await button.getAttribute('aria-label');
// 检查按钮是否已经点击过
if (!clickedButtons.has(ariaLabel)) {
console.log(`点击新按钮: ${ariaLabel}`);
await button.click();
clickedButtons.add(ariaLabel);
newButtonsFound = true;
await page.waitForTimeout(200);
}
} catch (e) {
console.log(`点击失败: ${e.message}`);
}
}
return newButtonsFound;
};
// 持续查找和点击,直到没有新按钮
let iteration = 1;
while (true) {
console.log(`\n${iteration} 次查找...`);
const foundNewButtons = await expandButtons();
if (!foundNewButtons) {
console.log('没有发现新的可展开按钮,结束查找');
break;
}
console.log(`已点击按钮数量: ${clickedButtons.size}`);
await page.waitForTimeout(500);
iteration++;
}
// 确保截图目录存在
const screenshotDir = path.join(__dirname, 'temp_screenshot');
fs.rmSync(screenshotDir, { recursive: true, force: true });
fs.mkdirSync(screenshotDir, { recursive: true });
console.log(`创建截图目录: ${screenshotDir}`);
const anchorHandles = await page.$$('a');
console.log(`找到 ${anchorHandles.length} 个链接`);
for (let i = 0; i < anchorHandles.length; i++) {
try {
const anchorHandle = anchorHandles[i];
// 先获取 <a> 标签的 href 与文本内容
const anchorData = await page.evaluate(el => {
return {
url: el.href,
text: el.innerText.trim()
};
}, anchorHandle);
// 生成文件名 (使用索引和文本内容的组合)
let filename = `link_${i+1}_${anchorData.text}`;
// 替换不合法的文件名字符
filename = filename.replace(/[\\/:*?"<>|]/g, '_');
// 限制文件名长度
if (filename.length > 100) filename = filename.substring(0, 100);
try {
// 使用更可靠的滚动方法
await page.evaluate(element => {
// 使用JavaScript的scrollIntoView更直接且兼容性更好
element.scrollIntoView({behavior: 'smooth', block: 'center'});
}, anchorHandle);
await page.waitForTimeout(500); // 给滚动和渲染更多时间
const rect = await anchorHandle.boundingBox();
filename = `${filename}_${rect.x}_${rect.y}_${rect.width}_${rect.height}.png`;
// 截图并保存
const screenshotPath = path.join(screenshotDir, filename);
await page.screenshot({ path: screenshotPath });
console.log(`处理链接 ${i+1}/${anchorHandles.length}: ${anchorData.text} - 已截图保存至 ${filename}`);
} catch (scrollError) {
console.log(`处理链接 ${i+1}/${anchorHandles.length}: ${anchorData.text} - 滚动失败但尝试截图`);
// 即使滚动失败也尝试截图
try {
const screenshotPath = path.join(screenshotDir, filename);
await page.screenshot({ path: screenshotPath });
} catch (e) {
console.error(`截图失败: ${e.message}`);
}
}
} catch (error) {
console.error(`处理第 ${i+1} 个链接时出错:`, error.message);
}
}
console.log(`链接总数: ${anchorHandles.length}, 截图已保存到 ${screenshotDir}`);
console.log('\n等待1000秒...');
await page.waitForTimeout(1000 * 1000);
} catch (error) {
console.error('发生错误:', error);
} finally {
// 关闭浏览器
await browser.close();
}
})();