javascript - 遍历 div 元素
问题描述
我是使用 javascript 和网络抓取的完整初学者,puppeteer
我正在尝试在
https://www.euroleague.net/main/results?gamenumber=28&phasetypecode=RS&seasoncode=E2019中获得简单的欧洲联赛回合的分数
通过inspecting
上面的分数列表,我发现分数列表是一个div
包含其他元素的元素,其中divs
显示了统计信息。
HTML
对于 2 支球队之间的单场比赛(此示例下方的比赛有更多 div)
//score list
<div class="wp-module wp-module-asidegames wp-module-5lfarqnjesnirthi">
//the data-code increases to "euro_245" ...
<div class="">
<div class="game played" data-code="euro_244" data-date="1583427600000" data-played="1">
<a href="/main/results/showgame?gamecode=244&seasoncode=E2019" class="game-link">
<div class="club">
<span class="name">Zenit St Petersburg</span>
<span class="score homepts winner">76</span>
</div>
<div class="club">
<span class="name">Zalgiris Kaunas</span>
<span class="score awaypts ">75</span>
</div>
<div class="info">
<span class="date">March 5 18:00 CET</span>
<span class="live">
LIVE <span class="minute"></span>
</span>
<span class="final">
FINAL
</span>
</div>
</a>
</div>
//more teams
</div>
</div>
我想要的是遍历外部 div 元素,让球队参加比赛和每场比赛的得分,并将它们存储在 json 文件中。但是,由于我是一个完整的初学者,我不明白如何遍历上面的 html。这是我获取元素的网络抓取代码:
const puppeteer = require('puppeteer');
const sleep = (delay) => new Promise((resolve) => setTimeout(resolve,delay));
async function getTeams(url){
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(url);
await sleep(3000);
const games = await page.$x('//*[@id="main-one"]/div/div/div/div[1]/div[1]/div[3]');
//this is where I will execute the iteration part to get the matches with their scores
await sleep(2000);
await browser.close();
}
getTeams('https://www.euroleague.net/main/results?gamenumber=28&phasetypecode=RS&seasoncode=E2019');
感谢您帮助指导我完成迭代部分。先感谢您
解决方案
游戏框最准确的选择器是div.game.played
(一个同时具有.game
和.played
CSS 类的 div),您需要计算符合此条件的元素。可以使用page.$$eval
( page .$$eval (selector, pageFunction[, ...args])
)Array.from(document.querySelectorAll(selector))
在页面内运行并将其作为第一个参数传递给pageFunction
.
当我们为特定数据字段使用元素索引时,我们运行一个带有元素长度的常规 for 循环。
如果您需要特定范围的“euro_xyz”,您可以在方法中获取data-code
属性值,并根据所需的“xyz”编号检查它们的编号。page.evaluate
Element.getAttribute
为了收集每个游戏的数据,我们可以定义一个收集器数组 ( gameObj
),它可以随着每次迭代而扩展。actualGame
在每次迭代中,我们用实际数据填充一个对象。
确定哪些子元素包含相应的数据值很重要,例如:主俱乐部的名称是'div.game.played > a > div:nth-child(1) > span:nth-child(1)'
div 子编号选择俱乐部,而跨度子编号在俱乐部名称和积分之间决定。循环的[i]
索引负责获取正确的游戏框的值(这就是它在开始时被计算在内的原因)。
例如:
const allGames = await page.$$('div.game.played')
const allGameLength = await page.$$eval('div.game.played', el => el.length)
const gameObj = []
for (let i = 0; i < allGameLength; i++) {
try {
let dataCode = await page.evaluate(el => el.getAttribute('data-code'), allGames[i])
dataCode = parseInt(dataCode.replace('euro_', ''))
if (dataCode > 243) {
const actualGame = {
homeClub: await page.evaluate(el => el.textContent, (await page.$$('div.game.played > a > div:nth-child(1) > span:nth-child(1)'))[i]),
awayClub: await page.evaluate(el => el.textContent, (await page.$$('div.game.played > a > div:nth-child(2) > span:nth-child(1)'))[i]),
homePoints: await page.evaluate(el => el.textContent, (await page.$$('div.game.played > a > div:nth-child(1) > span:nth-child(2)'))[i]),
awayPoints: await page.evaluate(el => el.textContent, (await page.$$('div.game.played > a > div:nth-child(2) > span:nth-child(2)'))[i]),
gameDate: await page.evaluate(el => el.textContent, (await page.$$('div.game.played > a > div:nth-child(3) > span:nth-child(1)'))[i])
}
gameObj.push(actualGame)
}
} catch (e) {
console.error(e)
}
}
console.log(JSON.stringify(gameObj))
puppeteer 中有一个page.waitFor
方法与您的函数的目的相同sleep
,但您也可以等待选择器出现 ( page.waitForSelector
)。
推荐阅读
- google-cloud-platform - 由于缺少 CMake,Google Cloud Build 失败
- firebase-realtime-database - 在 iOS 中的节点上更新值后,Firebase 节点意外删除自身
- javascript - 使用 background-image 属性制作动画是否最佳?
- python - 如何在终端外访问烧瓶应用程序?
- session-cookies - 负载均衡器的 Marklogic Rest API 事务问题
- python - AttributeError:'NoneType' 对象在基于空间分隔时没有属性'split'
- excel - 如何在excel中删除多个工作表中的重复值和原始值
- ruby-on-rails - 在 Rails+Passenger 服务器中启动应用程序作为服务
- raid - RAID5 故障,所有超级块丢失,无法重新组装阵列
- linux - 如何解决 xfce 中的 cytoscape 安装错误?