puppeteer - 如何从具有多个具有相同 class 的 div 的页面中提取内容
puppeteer - How to extract content from a page that have multiple divs with same class
我有一个简单的 puppeteer 脚本来抓取公告网站。我需要获取页面的内容,在我检查了 DOM 之后,我能够看到对于包含link 和正文。如何通过循环获取每个 div 的内容?
这是一个html页面结构的例子,大约有二十五个div相同的class,每一个都是一个公告。
<div class="container">
<div class="item-card bordertop show-in-related-free-list">
<!-- link and text are nested inside here -->
</div>
</div>
这是我目前的JS代码。我使用 headless-recorder-v2 chrome 扩展创建了它。
const puppeteer = require('puppeteer');
const browser = await puppeteer.launch({
headless: false,
slowMo: 300
})
const page = await browser.newPage()
const navigationPromise = page.waitForNavigation()
await page.goto('https://city.example.com/')
await page.setViewport({ width: 1280, height: 607 })
await page.waitForSelector('.bakec > #app > .alert > .btn')
await page.click('.bakec > #app > .alert > .btn')
await page.waitForSelector('.row > .col-md-4:nth-child(1) > .card > .cursor-pointer > .card-title-home')
await page.click('.row > .col-md-4:nth-child(1) > .card > .cursor-pointer > .card-title-home')
await navigationPromise
await page.waitForSelector('#lightbox-vm18 > .modal-dialog > .modal-content > .modal-footer > .btn-primary')
await page.click('#lightbox-vm18 > .modal-dialog > .modal-content > .modal-footer > .btn-primary')
await page.waitForSelector('.bakec > #app > main > .container')
await page.click('.bakec > #app > main > .container')
await page.waitForSelector('#app > main > .container > .item-card:nth-child(3) > .item-container')
// Here I want to loop over announces and store each link and title inside an array
//await page.click('#app > main > .container > .item-card:nth-child(3) > .item-container')
//await navigationPromise
//await browser.close()
更新
我已将这行代码添加到我的脚本中。我能够获得所需元素的数组,但我如何循环它们,foreEach
循环是否可以解决问题,或者我需要使用 for
循环??
const nodes = await page.$$('.item-heading > .item-title > a')
const announces = []
nodes.forEach( (el) => {
let href = el.getProperty('href')
announces.push(href)
})
console.log(announces);
如果我尝试循环 nodes
变量
,我会得到一个这样的数组
[
Promise { <pending> }, Promise { <pending> },
Promise { <pending> }, Promise { <pending> },
Promise { <pending> }, Promise { <pending> },
Promise { <pending> }, Promise { <pending> },
Promise { <pending> }, Promise { <pending> },
Promise { <pending> }, Promise { <pending> },
Promise { <pending> }, Promise { <pending> },
Promise { <pending> }, Promise { <pending> },
Promise { <pending> }, Promise { <pending> },
Promise { <pending> }, Promise { <pending> },
Promise { <pending> }, Promise { <pending> },
Promise { <pending> }, Promise { <pending> },
Promise { <pending> }
]
您可以使用 page.$$(selector)
获取与给定 CSS 选择器匹配的所有元素。
然后循环遍历元素并检索 属性 innerHTML
以获取每个 div (elementHandle.getProperty(propertyName)).
的内容
我有一个简单的 puppeteer 脚本来抓取公告网站。我需要获取页面的内容,在我检查了 DOM 之后,我能够看到对于包含link 和正文。如何通过循环获取每个 div 的内容?
这是一个html页面结构的例子,大约有二十五个div相同的class,每一个都是一个公告。
<div class="container">
<div class="item-card bordertop show-in-related-free-list">
<!-- link and text are nested inside here -->
</div>
</div>
这是我目前的JS代码。我使用 headless-recorder-v2 chrome 扩展创建了它。
const puppeteer = require('puppeteer');
const browser = await puppeteer.launch({
headless: false,
slowMo: 300
})
const page = await browser.newPage()
const navigationPromise = page.waitForNavigation()
await page.goto('https://city.example.com/')
await page.setViewport({ width: 1280, height: 607 })
await page.waitForSelector('.bakec > #app > .alert > .btn')
await page.click('.bakec > #app > .alert > .btn')
await page.waitForSelector('.row > .col-md-4:nth-child(1) > .card > .cursor-pointer > .card-title-home')
await page.click('.row > .col-md-4:nth-child(1) > .card > .cursor-pointer > .card-title-home')
await navigationPromise
await page.waitForSelector('#lightbox-vm18 > .modal-dialog > .modal-content > .modal-footer > .btn-primary')
await page.click('#lightbox-vm18 > .modal-dialog > .modal-content > .modal-footer > .btn-primary')
await page.waitForSelector('.bakec > #app > main > .container')
await page.click('.bakec > #app > main > .container')
await page.waitForSelector('#app > main > .container > .item-card:nth-child(3) > .item-container')
// Here I want to loop over announces and store each link and title inside an array
//await page.click('#app > main > .container > .item-card:nth-child(3) > .item-container')
//await navigationPromise
//await browser.close()
更新
我已将这行代码添加到我的脚本中。我能够获得所需元素的数组,但我如何循环它们,foreEach
循环是否可以解决问题,或者我需要使用 for
循环??
const nodes = await page.$$('.item-heading > .item-title > a')
const announces = []
nodes.forEach( (el) => {
let href = el.getProperty('href')
announces.push(href)
})
console.log(announces);
如果我尝试循环 nodes
变量
[
Promise { <pending> }, Promise { <pending> },
Promise { <pending> }, Promise { <pending> },
Promise { <pending> }, Promise { <pending> },
Promise { <pending> }, Promise { <pending> },
Promise { <pending> }, Promise { <pending> },
Promise { <pending> }, Promise { <pending> },
Promise { <pending> }, Promise { <pending> },
Promise { <pending> }, Promise { <pending> },
Promise { <pending> }, Promise { <pending> },
Promise { <pending> }, Promise { <pending> },
Promise { <pending> }, Promise { <pending> },
Promise { <pending> }, Promise { <pending> },
Promise { <pending> }
]
您可以使用 page.$$(selector)
获取与给定 CSS 选择器匹配的所有元素。
然后循环遍历元素并检索 属性 innerHTML
以获取每个 div (elementHandle.getProperty(propertyName)).