【Playwright】一次抓取音频的体验

696 阅读1分钟

翻页

目标页面做了重复的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)
  }
}

让抓取更逼真

  1. 降低工具的操作速度
  2. 浏览器设置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() });

gist.github.com/mackxu/51ab…