从无序列表中选择时如何最好地处理可变项目计数(和顺序)
How to best handle variable item count (and order) when selecting from unordered list
我从 ul 元素内的列表项中获取 innerText-Properties,该元素可以包含 4 到 10 个 li 项。
一些项目,如个人资料姓名、年龄和位置将始终存在,其他项目如当前学期、先前学位和其他关于学生个人资料的信息可以填写,但不是必须的。
因此,几乎每个配置文件和 :nth-child(x) - 元素的列表都会有不同的长度
将始终包含不同的信息。
我想用该数据提供一个对象构造函数,它期望将度数作为第 5 个参数。
您将如何检查列表中存在哪些信息并设置占位符,例如“n.a”。对于缺失值?这是我什至应该尝试在我的节点脚本中做的事情吗?或者这是以后在数据库中的工作?
我的 puppeteer 函数通过他们的 querySelectors 获取元素来解决这个问题,如下所示:
var ratingDetails = await page.evaluate(() => {
//get each element (that could be available) from a div
let text = document.querySelector("div.report-text").innerText
let age = document.querySelector
("div.card-block > ul.list-unstyled > li:nth-child(1) > span").innerText
let sex = document.querySelector
("div.card-block > ul.list-unstyled > li:nth-child(2) > span").innerText
let startYear = document.querySelector
("div.card-block > ul.list-unstyled > li:nth-child(3) > span").innerText
let studyForm = document.querySelector
("div.card-block > ul.list-unstyled > li:nth-child(4) > span").innerText
let location = document.querySelector
("div.card-block > ul.list-unstyled > li:nth-child(5) > span").innerText
[...and some more...]
})
//and then use the spread syntax to fill my constructor
await ratingDetails.map(facts => new ReportObject(...facts)));
非常感谢您提供有关如何处理该问题的任何建议!
经过大量尝试和错误后,我想出了以下解决方案:
- 遍历无序列表中的每个 li-element 并获取 innerText-Properties
let text = [];
for (let counter = 1; counter <= metaListe; counter++) {
text = await page.evaluate((counter) => {
let liElements = document.querySelector(`div.card-block > ul.list-unstyled > li:nth-child(${counter})`).innerText.trim();
return liElements;
}, counter);
- 为所有可能的 li-items
定义一些 regEx-Patterns
const patt_jahrStudBeginn = /^Studienbeginn/;
const patt_abschluss = /^Abschluss/i;
const patt_aktFS = /^Aktuelles/;
const patt_studienForm = /^Studienform/;
[and some more...]
- 将步骤 1 中的 innerText-Properties 与模式进行比较,如果匹配则 return 一个变量(并继续下一个 string/innerText
if(!document.querySelector(`div.card-block > ul.list-unstyled > li:nth-child(${counter})`))
{return;}
else{
if(patt_studienForm.test(text)) {
let studForm = document.querySelector(`div.card-block > ul.list-unstyled > li:nth-child(${counter}) > span`).innerText;
}else{
if(patt_studienDauer.test(text)) {
let studDauer = document.querySelector(`div.card-block > ul.list-unstyled > li:nth-child(${counter}) > span`).innerText;
}else{
if(patt_jahrStudBeginn.test(text)) {
let jahrBeginn = document.querySelector(`div.card-block > ul.list-unstyled > li:nth-child(${counter}) > span`).innerText;
}else{
if(patt_aktFS.test(text)) {
let aktFS = document.querySelector(`div.card-block > ul.list-unstyled > li:nth-child(${counter}) > span`).innerText;
[...and more...]
和 return 所有包含来自 page.evaluate() 函数的不同信息的变量。
我花了很长时间才明白,我必须将任何计数变量传递给 .evaluate() 方法才能使用其中的当前循环索引来引用 n-th 列表元素。
超深的 if-condition 不可能是好的代码。我可能会在一个单独的问题中询问如何增强与数组的这种类型的比较。但它按原样工作。
我从 ul 元素内的列表项中获取 innerText-Properties,该元素可以包含 4 到 10 个 li 项。 一些项目,如个人资料姓名、年龄和位置将始终存在,其他项目如当前学期、先前学位和其他关于学生个人资料的信息可以填写,但不是必须的。 因此,几乎每个配置文件和 :nth-child(x) - 元素的列表都会有不同的长度 将始终包含不同的信息。 我想用该数据提供一个对象构造函数,它期望将度数作为第 5 个参数。
您将如何检查列表中存在哪些信息并设置占位符,例如“n.a”。对于缺失值?这是我什至应该尝试在我的节点脚本中做的事情吗?或者这是以后在数据库中的工作?
我的 puppeteer 函数通过他们的 querySelectors 获取元素来解决这个问题,如下所示:
var ratingDetails = await page.evaluate(() => {
//get each element (that could be available) from a div
let text = document.querySelector("div.report-text").innerText
let age = document.querySelector
("div.card-block > ul.list-unstyled > li:nth-child(1) > span").innerText
let sex = document.querySelector
("div.card-block > ul.list-unstyled > li:nth-child(2) > span").innerText
let startYear = document.querySelector
("div.card-block > ul.list-unstyled > li:nth-child(3) > span").innerText
let studyForm = document.querySelector
("div.card-block > ul.list-unstyled > li:nth-child(4) > span").innerText
let location = document.querySelector
("div.card-block > ul.list-unstyled > li:nth-child(5) > span").innerText
[...and some more...]
})
//and then use the spread syntax to fill my constructor
await ratingDetails.map(facts => new ReportObject(...facts)));
非常感谢您提供有关如何处理该问题的任何建议!
经过大量尝试和错误后,我想出了以下解决方案:
- 遍历无序列表中的每个 li-element 并获取 innerText-Properties
let text = [];
for (let counter = 1; counter <= metaListe; counter++) {
text = await page.evaluate((counter) => {
let liElements = document.querySelector(`div.card-block > ul.list-unstyled > li:nth-child(${counter})`).innerText.trim();
return liElements;
}, counter);
- 为所有可能的 li-items 定义一些 regEx-Patterns
const patt_jahrStudBeginn = /^Studienbeginn/;
const patt_abschluss = /^Abschluss/i;
const patt_aktFS = /^Aktuelles/;
const patt_studienForm = /^Studienform/;
[and some more...]
- 将步骤 1 中的 innerText-Properties 与模式进行比较,如果匹配则 return 一个变量(并继续下一个 string/innerText
if(!document.querySelector(`div.card-block > ul.list-unstyled > li:nth-child(${counter})`))
{return;}
else{
if(patt_studienForm.test(text)) {
let studForm = document.querySelector(`div.card-block > ul.list-unstyled > li:nth-child(${counter}) > span`).innerText;
}else{
if(patt_studienDauer.test(text)) {
let studDauer = document.querySelector(`div.card-block > ul.list-unstyled > li:nth-child(${counter}) > span`).innerText;
}else{
if(patt_jahrStudBeginn.test(text)) {
let jahrBeginn = document.querySelector(`div.card-block > ul.list-unstyled > li:nth-child(${counter}) > span`).innerText;
}else{
if(patt_aktFS.test(text)) {
let aktFS = document.querySelector(`div.card-block > ul.list-unstyled > li:nth-child(${counter}) > span`).innerText;
[...and more...]
和 return 所有包含来自 page.evaluate() 函数的不同信息的变量。 我花了很长时间才明白,我必须将任何计数变量传递给 .evaluate() 方法才能使用其中的当前循环索引来引用 n-th 列表元素。
超深的 if-condition 不可能是好的代码。我可能会在一个单独的问题中询问如何增强与数组的这种类型的比较。但它按原样工作。