【发布时间】:2019-04-17 09:36:51
【问题描述】:
我对 Puppeteer 和等待/异步语法很陌生。我正在尝试构建一个机器人来尝试从 Instagram 获取数据。具体来说,我想获得给定个人资料的关注者。一切正常,直到弹出追随者窗口。我想选择要在其上滚动的 DOM 元素,并在每次迭代时将跟随者推送到数组中。我搜索了论坛并尝试了不同的方法,但它总是返回未定义。我能够获得一个 ElementHandle (scrollBox3) 并获得像 scrollHeight 这样的属性,但不能获得实际的 DOM 元素。 代码如下,对文件的不同部分进行了描述。
任何帮助将不胜感激:)
下一部分选择 DOM 元素。 CRED 文件是我的用户名和密码所在的位置。
const puppeteer = require('puppeteer');
const CREDS = require('./creds');
// Dom Elements
const loginPage = 'https://www.instagram.com/accounts/login/';
const usernameInput = 'input[name="username"]';
const passwordInput = 'input[name="password"]';
const submitButton = 'button[type="submit"]';
const userToSearch = 'nicolekidman';
const searchUser = `https://www.instagram.com/${userToSearch}`;
const followers = `a[href='/${userToSearch}/followers/']`;
这部分以数组的形式记录scrollBox中可见的followers。
// Extract followers from a user profile
const extractFollowers = () => {
let followers = [];
let elements = document.getElementsByClassName('FPmhX notranslate _0imsa ');
for (let element of elements)
followers.push(element.textContent);
return followers;
}
这是代码中断的滚动功能。基本上我想在这个滚动框上循环和滚动,但我无法抓住 DOM 元素。
// Scrolling Function
async function scrapeInfiniteScrollItems(
page,
extractFollowers,
followersTargetCount,
scrollDelay = 1000,
) {
let items = [];
// Next 2 lines return undefined
// .isgrP and .PZuss are classes inside this div, PZuss is the one we want to scroll on
let scrollBox1 = await page.$eval('.isgrP', el => el.querySelector('body > div:nth-child(15) > div > div > div.isgrP > ul > div'));
let scrollBox2 = await page.$eval('body > div:nth-child(15) > div > div > div.isgrP > ul > div', el => el);
// Next line returns an ElementHandle
let scrollBox3 = await page.$('.PZuss');
console.log(scrollBox3);
let scrollBoxHeight = await page.$eval('.PZuss', el => el.scrollHeight);
console.log(scrollBoxHeight);
try {
while (items.length < followersTargetCount) {
items = await page.evaluate(extractFollowers);
console.log(extractFollowers());
// await page.evaluate('scrollBox.scrollTo(0, scrollable_popup.scrollHeight)');
// await page.waitForFunction(`scrollBox.scrollHeight > ${previousHeight}`);
// await page.waitFor(scrollDelay);
}
} catch(e) { }
return items;
}
这是实际的异步功能,我正在做所有工作以访问 Instagram 并调用滚动功能来记录给定个人资料的关注者。
(async() => {
// headless false for visual debugging in browser
const browser = await puppeteer.launch({
headless: false
});
const page = await browser.newPage();
await page.goto(loginPage, {waitUntil: 'networkidle2'});
// Type username
await page.click(usernameInput);
await page.keyboard.type(CREDS.username);
// Type password and submit
await page.click(passwordInput);
await page.keyboard.type(CREDS.password);
await page.click(submitButton);
await page.waitFor(2000);
// Search User with URL
await page.goto(searchUser);
await page.click(followers);
await page.waitFor(2000);
const findFollowers = await scrapeInfiniteScrollItems(page, extractFollowers, 100);
console.log(findFollowers);
await page.screenshot({ path: '../screenshots/insta.png' });
// await browser.close();
})();
【问题讨论】:
标签: javascript scroll async-await instagram puppeteer