puppeteer / node.js - 进入页面,点击加载更多直到加载所有评论,将页面保存为 mhtml
puppeteer / node.js - enter page, click load more until all comments load, save page as mhtml
我想要完成的是进入这个网站 https://www.discoverpermaculture.com/permaculture-masterclass-video-1 等待它加载,从 disqus 加载所有评论(单击 'Load more comments' 按钮直到它不再存在)并将页面保存为 mhtml供离线使用。
我在这里发现了类似的问题 但不幸的是,由于某种原因,尝试检测“加载更多评论”按钮不起作用。
似乎 WaitForSelector('a.load-more__button') 没有工作,因为它打印出来的所有内容都是“不可见的”。
这是我的代码
const puppeteer = require('puppeteer');
const url = "https://www.discoverpermaculture.com/permaculture-masterclass-video-1";
const isElementVisible = async (page, cssSelector) => {
let visible = true;
await page
.waitForSelector(cssSelector, { visible: true, timeout: 4000 })
.catch(() => {
console.log('not visible');
visible = false;
});
return visible;
};
async function run () {
let browser = await puppeteer.launch({
headless: true,
defaultViewport: null,
args: [
'--window-size=1920,10000',
],
});
const page = await browser.newPage();
const fs = require('fs');
await page.goto(url);
await page.waitForNavigation();
await page.waitForTimeout(4000)
const selectorForLoadMoreButton = 'a.load-more__button';
let loadMoreVisible = await isElementVisible(page, selectorForLoadMoreButton);
while (loadMoreVisible) {
console.log('load more visible');
await page
.click(selectorForLoadMoreButton)
.catch(() => {});
await page.waitForTimeout(4000);
loadMoreVisible = await isElementVisible(page, selectorForLoadMoreButton);
}
const cdp = await page.target().createCDPSession();
const { data } = await cdp.send('Page.captureSnapshot', { format: 'mhtml' });
fs.writeFileSync('page.mhtml', data);
browser.close();
}
run();
您正在等待处理 ajax 请求。您可以简单地保存评论总数(DISQUS 插件的左上角)并将其与评论数组进行比较,一旦数组等于总数,那么您就检索了每条评论。
我在等待 ajax 请求时发布了一些东西,您可以在这里看到它:.
或者,更简单的方法是只使用 DISQUS api。
评论是公开的。您可以只使用网站上的 api 密钥:
parameter
options
limit
Default to 50
. Maximum is 100
.
thread
Thread number. eg: 7187962034
.
forum
Forum id. eg: pdc2018
.
order
desc
, asc
, popular
.
cursor
Probably the page number. Format is 1:0:0
. eg: Page 2 would be 2:0:0
.
api_key
The platform api key. Here the api key is E8Uh5l5fHZ6gD8U3KycjAIAk46f68Zw7C6eW8WSjZvCLXebZ7p0r1yrYDrLilk2F
.
如果您必须遍历不同的页面,您需要拦截 xhr
响应以检索线程号。
原来问题是 disqus 评论在 iframe 中
//needed to add those 2 lines
const elementHandle = await page.waitForSelector('iframe');
const frame = await elementHandle.contentFrame();
//and change 'page' to 'frame' below
let loadMoreVisible = await isElementVisible(frame, selectorForLoadMoreButton);
while (loadMoreVisible) {
console.log('load more visible');
await frame
.click(selectorForLoadMoreButton)
.catch(() => {});
await frame.waitForTimeout(4000);
loadMoreVisible = await isElementVisible(frame, selectorForLoadMoreButton);
}
此更改后效果完美
我想要完成的是进入这个网站 https://www.discoverpermaculture.com/permaculture-masterclass-video-1 等待它加载,从 disqus 加载所有评论(单击 'Load more comments' 按钮直到它不再存在)并将页面保存为 mhtml供离线使用。
我在这里发现了类似的问题
似乎 WaitForSelector('a.load-more__button') 没有工作,因为它打印出来的所有内容都是“不可见的”。
这是我的代码
const puppeteer = require('puppeteer');
const url = "https://www.discoverpermaculture.com/permaculture-masterclass-video-1";
const isElementVisible = async (page, cssSelector) => {
let visible = true;
await page
.waitForSelector(cssSelector, { visible: true, timeout: 4000 })
.catch(() => {
console.log('not visible');
visible = false;
});
return visible;
};
async function run () {
let browser = await puppeteer.launch({
headless: true,
defaultViewport: null,
args: [
'--window-size=1920,10000',
],
});
const page = await browser.newPage();
const fs = require('fs');
await page.goto(url);
await page.waitForNavigation();
await page.waitForTimeout(4000)
const selectorForLoadMoreButton = 'a.load-more__button';
let loadMoreVisible = await isElementVisible(page, selectorForLoadMoreButton);
while (loadMoreVisible) {
console.log('load more visible');
await page
.click(selectorForLoadMoreButton)
.catch(() => {});
await page.waitForTimeout(4000);
loadMoreVisible = await isElementVisible(page, selectorForLoadMoreButton);
}
const cdp = await page.target().createCDPSession();
const { data } = await cdp.send('Page.captureSnapshot', { format: 'mhtml' });
fs.writeFileSync('page.mhtml', data);
browser.close();
}
run();
您正在等待处理 ajax 请求。您可以简单地保存评论总数(DISQUS 插件的左上角)并将其与评论数组进行比较,一旦数组等于总数,那么您就检索了每条评论。
我在等待 ajax 请求时发布了一些东西,您可以在这里看到它:
或者,更简单的方法是只使用 DISQUS api。
评论是公开的。您可以只使用网站上的 api 密钥:
parameter | options |
---|---|
limit |
Default to 50 . Maximum is 100 . |
thread |
Thread number. eg: 7187962034 . |
forum |
Forum id. eg: pdc2018 . |
order |
desc , asc , popular . |
cursor |
Probably the page number. Format is 1:0:0 . eg: Page 2 would be 2:0:0 . |
api_key |
The platform api key. Here the api key is E8Uh5l5fHZ6gD8U3KycjAIAk46f68Zw7C6eW8WSjZvCLXebZ7p0r1yrYDrLilk2F . |
如果您必须遍历不同的页面,您需要拦截 xhr
响应以检索线程号。
原来问题是 disqus 评论在 iframe 中
//needed to add those 2 lines
const elementHandle = await page.waitForSelector('iframe');
const frame = await elementHandle.contentFrame();
//and change 'page' to 'frame' below
let loadMoreVisible = await isElementVisible(frame, selectorForLoadMoreButton);
while (loadMoreVisible) {
console.log('load more visible');
await frame
.click(selectorForLoadMoreButton)
.catch(() => {});
await frame.waitForTimeout(4000);
loadMoreVisible = await isElementVisible(frame, selectorForLoadMoreButton);
}
此更改后效果完美