向下滚动到页面底部可以通过两种方式完成:
- 使用scrollIntoView(滚动到页面底部可以创建更多内容的部分)和选择器(即
document.querySelectorAll('.class_name').length
检查是否生成了更多内容)
- 使用scrollBy(逐步向下滚动页面)和setTimeout或setInterval(逐步检查我们是否在页面底部)
这是一个在纯 JavaScript 中使用scrollIntoView
和选择器(假设.class_name
是我们滚动到更多内容的选择器)的实现,我们可以在浏览器中运行它:
方法一:使用 scrollIntoView 和选择器
const delay = 3000;
const wait = (ms) => new Promise(res => setTimeout(res, ms));
const count = async () => document.querySelectorAll('.class_name').length;
const scrollDown = async () => {
document.querySelector('.class_name:last-child')
.scrollIntoView({ behavior: 'smooth', block: 'end', inline: 'end' });
}
let preCount = 0;
let postCount = 0;
do {
preCount = await count();
await scrollDown();
await wait(delay);
postCount = await count();
} while (postCount > preCount);
await wait(delay);
在此方法中,我们比较.class_name
滚动前 ( preCount
) 和滚动后 ( postCount
)的选择器数量,以检查我们是否位于页面底部:
if (postCount > precount) {
// NOT bottom of page
} else {
// bottom of page
}
这里有两种可能的实现,使用setTimeout
或setInterval
使用scrollBy
纯 JavaScript,我们可以在浏览器控制台中运行:
方法 2a:使用 setTimeout 和 scrollBy
const distance = 100;
const delay = 100;
while (document.scrollingElement.scrollTop + window.innerHeight < document.scrollingElement.scrollHeight) {
document.scrollingElement.scrollBy(0, distance);
await new Promise(resolve => { setTimeout(resolve, delay); });
}
方法 2b:使用 setInterval 和 scrollBy
const distance = 100;
const delay = 100;
const timer = setInterval(() => {
document.scrollingElement.scrollBy(0, distance);
if (document.scrollingElement.scrollTop + window.innerHeight >= document.scrollingElement.scrollHeight) {
clearInterval(timer);
}
}, delay);
在这种方法中,我们是在比较document.scrollingElement.scrollTop + window.innerHeight
与document.scrollingElement.scrollHeight
检查我们是否在页面的底部:
if (document.scrollingElement.scrollTop + window.innerHeight < document.scrollingElement.scrollHeight) {
// NOT bottom of page
} else {
// bottom of page
}
如果上面的任一 JavaScript 代码将页面一直向下滚动到底部,那么我们就知道它正在工作,我们可以使用 Puppeteer 自动执行此操作。
下面是示例 Puppeteer Node.js 脚本,它们将向下滚动到页面底部并在关闭浏览器之前等待几秒钟。
Puppeteer 方法 1:使用带有选择器 ( .class_name
) 的scrollIntoView
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
headless: false,
defaultViewport: null,
args: ['--window-size=800,600']
});
const page = await browser.newPage();
await page.goto('https://example.com');
const delay = 3000;
let preCount = 0;
let postCount = 0;
do {
preCount = await getCount(page);
await scrollDown(page);
await page.waitFor(delay);
postCount = await getCount(page);
} while (postCount > preCount);
await page.waitFor(delay);
await browser.close();
})();
async function getCount(page) {
return await page.$$eval('.class_name', a => a.length);
}
async function scrollDown(page) {
await page.$eval('.class_name:last-child', e => {
e.scrollIntoView({ behavior: 'smooth', block: 'end', inline: 'end' });
});
}
Puppeteer 方法 2a:使用 setTimeout 和 scrollBy
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
headless: false,
defaultViewport: null,
args: ['--window-size=800,600']
});
const page = await browser.newPage();
await page.goto('https://example.com');
await scrollToBottom(page);
await page.waitFor(3000);
await browser.close();
})();
async function scrollToBottom(page) {
const distance = 100; // should be less than or equal to window.innerHeight
const delay = 100;
while (await page.evaluate(() => document.scrollingElement.scrollTop + window.innerHeight < document.scrollingElement.scrollHeight)) {
await page.evaluate((y) => { document.scrollingElement.scrollBy(0, y); }, distance);
await page.waitFor(delay);
}
}
Puppeteer 方法 2b:使用 setInterval 和 scrollBy
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
headless: false,
defaultViewport: null,
args: ['--window-size=800,600']
});
const page = await browser.newPage();
await page.goto('https://example.com');
await page.evaluate(scrollToBottom);
await page.waitFor(3000);
await browser.close();
})();
async function scrollToBottom() {
await new Promise(resolve => {
const distance = 100; // should be less than or equal to window.innerHeight
const delay = 100;
const timer = setInterval(() => {
document.scrollingElement.scrollBy(0, distance);
if (document.scrollingElement.scrollTop + window.innerHeight >= document.scrollingElement.scrollHeight) {
clearInterval(timer);
resolve();
}
}, delay);
});
}