JavaScript - 从多个数组填充对象构造函数
Posted
技术标签:
【中文标题】JavaScript - 从多个数组填充对象构造函数【英文标题】:JavaScript - populate object constructor from multiple arrays 【发布时间】:2020-10-30 08:25:06 【问题描述】:我正在从一个网站收集多个内部文本属性,该网站在其页面上重复元素(24 个大学简介,包括名称、平均评分、课程数量等)。
我在一所大学使用querySelector()
测试了我的小程序,以收集我想要的4-5 innerText,使用var u = await Promise.allSettled([arr1, arr2, arr3, arr4, arr5])
将它们组合在一起,并使用我在顶部定义的构造函数var currUniv = new University(...myArrayOfFacts)
。到目前为止一切顺利(至少结果......)
由于该页面一次/在一个页面上提供 24 个大学项目(并且都在相同的结构中),我现在想使用 querySelectorAll()
一次抓取 5 个数组,每个数组包含 24 个元素。如果我坚持使用var u = await Promise.allSettled([arr1, arr2, arr3, arr4, arr5])
,我最终会得到一个由 5 个数组组成的数组,现在不知道(而且似乎无法找到成功的 google 方法)我如何一次将每个数组的一个元素提供给我的构造函数。
我应该首先避免将所有东西都塞进一个大数组中吗? 我这样做是因为我认为我需要等待所有承诺来解决...... 或者我应该在什么时候开始循环遍历数组?
一切都是异步的。我稍微缩短了代码: 就像我进一步写的那样——对于一组 DOM 元素/一所大学来说效果很好。
非常感谢任何提示我正确的方向!
const puppeteer = require('./node_modules/puppeteer');
const startUrl = "https://www.studycheck.de/hochschulen/";
//constructor - shortend
function HSMain(name, ...)
this.nameHS = name;
this...
const hsfPageVisits = async () =>
try
const browser = await puppeteer.launch(headless: true);
const page = await browser.newPage();
await page.goto(startUrl, waitUntil: 'domcontentloaded');
// get first element (name)
var nameHS = await page.evaluate(() =>
let name = Array.from(document.querySelectorAll('div .title a')).map(node => node.innerText);
return name;
);
// get second element (rating)
var rating = await page.evaluate(() =>
let rate = Array.from(document.querySelectorAll('div .rating-container > div .rating-value')).map(node => node.innerText.trim());
return rate;
);
[...more DOM - elements...]
// wait for all promises to resolve
var univArr = await Promise.allSettled([nameHS, rating, ..., ..., ...]);
// spread the array into the object constructor
var myObj = await new HSMain(...univArr);
await browser.close();
catch(e)
console.log("error", e);
;
hsfPageVisits();
【问题讨论】:
【参考方案1】:所以你有一个名称数组和另一个用于评级等。这些数组的每个索引对应于同一所大学,因此只需map
其中一个数组并使用map
提供的索引从其余数组中获取值,不幸的是您不能在此处使用扩展语法:
let universities = nameHS.map((name, i) =>
new University(name, rating[i], theNextArray[i], theArrayAfterThat[i], ...)
);
我的方法是一次获取每所大学的所有“事实”,而不是分别在不同的数组中。每所大学都会将其事实分组在一个对象或数组中,这将大大缩短代码,如下所示:
try
const browser = await puppeteer.launch( headless: true );
const page = await browser.newPage();
await page.goto(startUrl, waitUntil: 'domcontentloaded' );
var universitiesFacts = await page.evaluate(() =>
let universities = Array.from(document.querySelectorAll(".institute-item")); // first get all university (each university info is contained in an element with a class 'institute-item')
return universities.map(university => [ // for each .institute-item element
university.querySelector(".title a").textContent.trim(), // get the name (using querySelector on the .institute-item element)
university.querySelector(".rating-value").textContent.trim(), // get the rating
// ... the rest of facts for the current university
]);
);
let universities = universitiesFacts.map(facts => new University(...facts)); // now we can use the spread syntax
await browser.close();
【讨论】:
以上是关于JavaScript - 从多个数组填充对象构造函数的主要内容,如果未能解决你的问题,请参考以下文章