Как я могу отформатировать каждый элемент td как свойство объекта, очищая таблицу с помощью Puppeteer? - PullRequest
1 голос
/ 18 июня 2020

Я хочу создать объект из таблицы HTML с каждым td innerText в качестве свойств объекта. Проблема в том, что я могу хранить только весь текст внутри одного свойства, а не отдельных.

puppeteer.launch().then(async function(browser) {
const page = await browser.newPage();
await page.goto('https://en.wikipedia.org/wiki/List_of_countries_and_dependencies_by_population');


const countriesData = await page.$$eval('table tr ', countries => {
    return countries.map(country => {
        return {country: country.innerText};
    })
})

console.log(countriesData)

await browser.close();})

Он регистрирует каждую страну следующим образом:

{country: '1\t China[b]\t1,403,148,200\t18.0%\t18 Jun 2020\tNational population clock[3]'},

Но хочу этого

{id, name, population, percentage,},

1 Ответ

1 голос
/ 18 июня 2020

Вы можете решить проблему с помощью простого для l oop.

1.) Определите структуру объекта, в моем примере я использовал JavaScript class CountryItem , вы, конечно, можете использовать все, что захотите. Затем создайте пустой массив (countries), в котором мы можем собрать все экземпляры стран.

2.) Получите точное количество строк таблицы (countriesLength в примере, вам нужно будет добавить + 1 к его значению, чтобы также достичь последнего элемента).

3.) Напишите a для l oop, который выполняет итерацию по всем <tr> -s.

4.) Данные из <td> -s можно получить с помощью их точных селекторов, где:

  • tr:nth-child(${ **number of row** }) и

  • td:nth-child(${ **1 = Rank; 2 = Name; 3 = Country name; 4 = Population etc.** }).

5.) На каждой итерации создайте новый CountryItem с фактическими очищенными строками и pu sh для основного объекта (пустой массив, который мы определили в начале).

Пример кода:

const puppeteer = require('puppeteer')

puppeteer.launch().then(async function (browser) {
  const page = await browser.newPage()
  await page.goto('https://en.wikipedia.org/wiki/List_of_countries_and_dependencies_by_population')

  const countries = []
  class CountryItem {
    constructor(id, name, population, percentage, date, source) {
      this.id = id
      this.name = name
      this.population = population
      this.percentage = percentage
      this.date = date
      this.source = source
    }
  }
  const tableSelector = '#mw-content-text > div > table > tbody'
  const countriesLength = await page.$$eval(`${tableSelector} > tr`, el => el.length)

  // iterate over tr:nth-child(${i}) on all rows
  for (let i = 1; i < countriesLength + 1; i++) {
    const id = i
    const name = await page.evaluate(el => el.innerText, await page.$(`${tableSelector} > tr:nth-child(${i}) > td:nth-child(2)`))
    const population = await page.evaluate(el => el.innerText, await page.$(`${tableSelector} > tr:nth-child(${i}) > td:nth-child(3)`))
    const percentage = await page.evaluate(el => el.innerText, await page.$(`${tableSelector} > tr:nth-child(${i}) > td:nth-child(4)`))
    const date = await page.evaluate(el => el.innerText, await page.$(`${tableSelector} > tr:nth-child(${i}) > td:nth-child(5)`))
    const source = await page.evaluate(el => el.innerText, await page.$(`${tableSelector} > tr:nth-child(${i}) > td:nth-child(6)`))

    const actualCountryItem = new CountryItem(id, name, population, percentage, date, source)
    countries.push(actualCountryItem)
  }
  console.log(countries)

  await browser.close()
})

Пример вывода:

...
  CountryItem {
    id: 99,
    name: ' Austria',
    population: '8,902,600',
    percentage: '0.114%',
    date: '1 Jan 2020',
    source: 'Quarterly provisional figure[91]'
  },
  CountryItem {
    id: 100,
    name: ' Switzerland',
    population: '8,603,899',
    percentage: '0.110%',
    date: '31 Dec 2019',
    source: 'National provisional figure[92]'
  },
  ...
]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...