翻页
目标页面做了重复的DOM结构,通过开发者工具发现,其中一个是display:none ,可以借助visible=true过滤掉。
async function nextPage(pageNo) {
const input = page.locator('[placeholder="请输入页码"]:visible');
// await input.scrollIntoViewIfNeeded();
await input.fill(String(pageNo));
await page.locator('button >> text=跳转 >> visible=true').click();
}
点击播放按钮
播单列表中的播放按钮做了特殊处理,页面上不响应css hover,并且宽度显示为0,所以不能直接模拟触发点击。通过观察发现,操作DOM,用play替换default样式类后,能正常点击播放。
async function showAudioNameAndURL(el) {
// 获取音乐的名称
const link = await el.$('a');
const name = await link.getAttribute('title');
console.log(name);
sounds.push(name);
// 显示播放按钮
const btn = await el.$('.all-icon');
await btn.evaluate(node => {
node.classList.remove('default');
node.classList.add('play');
});
// 监听网络,抓取到audio url
const [req] = await Promise.all([
page.waitForRequest(/\.m4a/),
btn.click(),
]);
console.log(req.url());
sounds.push(req.url());
}
翻页&抓取
const maxPageNo = page.locator('.sound-list .pagination-page li >> nth=-2');
const pageCount = Number(await maxPageNo.innerText());
for (let index = 1; index < pageCount; index++) {
await getLinks();
await nextPage(index + 1)
}
async function getLinks() {
const list = await page.$$('.sound-list > ul > li');
for (const el of list) {
await showAudioNameAndURL(el)
}
}
让抓取更逼真
- 降低工具的操作速度
- 浏览器设置UA
// the slowMo option to slow down execution
const browser = await chromium.launch({ headless: false, slowMo: 2000 });
// import fakeUA from 'fake-ua'
const context = await browser.newContext({ userAgent: fakeUA.pc() });