Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 返回相同值的循环(在Puppeter中)内的“page.evaluate()”_Javascript_Html_Node.js_Closures_Puppeteer - Fatal编程技术网

Javascript 返回相同值的循环(在Puppeter中)内的“page.evaluate()”

Javascript 返回相同值的循环(在Puppeter中)内的“page.evaluate()”,javascript,html,node.js,closures,puppeteer,Javascript,Html,Node.js,Closures,Puppeteer,概述: 这不是实际问题,但我已将问题简化,并将其转化为更容易理解的问题。我从一个页面返回相同的数据。在循环的每次迭代中,evaluate都放在for…of循环中。我想这是因为闭包,我很久没有用JS编程了,所以我不能用异步函数实现IIFE。此外,我认为我们不能用异步函数实现forEach而不是for…if。如果问题太长,我提前道歉,但我想说清楚 说明: 我正试图刮一个网页有杂货店的数据。可以从“选择元素”下拉列表中选择蔬菜、水果、奶制品、面包店等杂货店的类型。选择该选项时,将根据类型显示杂货清单

概述: 这不是实际问题,但我已将问题简化,并将其转化为更容易理解的问题。我从一个页面返回相同的数据。在循环的每次迭代中,evaluate都放在for…of循环中。我想这是因为闭包,我很久没有用JS编程了,所以我不能用异步函数实现IIFE。此外,我认为我们不能用异步函数实现forEach而不是for…if。如果问题太长,我提前道歉,但我想说清楚

说明: 我正试图刮一个网页有杂货店的数据。可以从“选择元素”下拉列表中选择蔬菜、水果、奶制品、面包店等杂货店的类型。选择该选项时,将根据类型显示杂货清单

杂货店选择是允许我们选择选项的选择标记的id i、 e.选择食品杂货店 杂货项目是包含每个杂货项目数据的div类。div.screery-item例如:对于杂货类水果,它包含香蕉、苹果等的数据。每个div分别有一个和两个元素用于名称、价格和可用性。 我在数组[‘水果’、‘蔬菜’、‘面包店’]中循环项目,然后将每个项目作为JSON添加到数组grovery_info中,并从page.evaluate返回grovery_inf。U all是分配返回值的变量

这是我遇到问题的代码部分

async function scrape_and_display(item) {
  await page.select("select#grocery-choice", item);
  await page.waitForSelector("div.grocery-item");
  const grocery_all = await page.evaluate((x) => {
    let grocery_info = [];
    let grocery_list = document.querySelectorAll("div.grocery-item");
    grocery_list.forEach((item) => {
      grocery_info.push({
        name: item.getElementsByTagName("h4")[0].innerText,
        price: item.getElementsByTagName("p")[0].innerText,
        availability: item.getElementsByTagName("p")[1].innerText,
      });
    });
    return grocery_info;
  });
  console.log(grocery_all);
}

for (item of ["fruit", "vegetable", "bakery"]) {
  await scrape_and_display(item);
}
所需输出:

电流输出:

这里是实际的问题,我需要的不是杂货类,而是尼泊尔各州,我需要的不是杂货类,而是学校;我没有登录到控制台,而是将其导出为CSV文件。 如果选中CSV文件,您将找到所有相同的数据,即下拉列表的最后一项,即最后一个选项。 以下是工作代码:


任何帮助都将不胜感激。提前感谢。

重新呈现学校列表似乎需要一些时间,您不必等待这一时间,因此您的代码只是太快地刮取了相同的数据。您可以等待一些更改,例如更改列表上方的主信息文本:

异步函数scrape\u和\u saveitem{ const previousData=等待页面。评估 =>document.querySelector'divschoolData'.innerText ; 等待page.selectddlState,item.value; wait page.waitForFunction data=>{return data!==document.querySelector'divschoolData'.innerText;}, {}, 以前的数据, ; 试一试{ // ... 顺便说一句,尝试始终添加const/let for循环变量以防止范围问题:

对于selectOptions的常量项{
使用严格模式不要忘记这一点

你确定更改选择有效吗?你能用headless:false确认吗?@Vaviloff:谢谢你的回复。事实上我已经编辑了这篇文章,实际的代码是最后一个,它工作得很好。所以,是的,选择有效。我只是想创建一个更容易理解的问题,所以我创建了一个关于食品和水果。任何帮助都将被感谢。非常感谢,这很有效。这并没有出现在我的脑海中,我朝着错误的方向寻求解决方案,这将花费很长时间来解决。谢谢!!
[
  { name: 'Banana', price: '$10 / kg', availability: 'In Stock' },
  { name: 'Apple', price: '$20 / kg', availability: 'In Stock' },
  { name: 'Grape', price: '$45 / kg', availability: 'Out of Stock' },
  { name: 'Orange', price: '$10 / kg', availability: 'In Stock' }
]
[
  { name: 'Brocli', price: '$10 / kg', availability: 'In Stock' },
  { name: 'Pumpkin', price: '$15 / kg', availability: 'In Stock' },
  { name: 'Lettuce', price: '$7 / kg', availability: 'In Stock' }
]
[
  { name: 'Bread', price: '$15 / piece', availability: 'In Stock' },
  { name: 'Apple Pie', price: '$20 / piece', availability: 'In Stock' }
]
[
  { name: 'Bread', price: '$15 / piece', availability: 'In Stock' },
  { name: 'Apple Pie', price: '$20 / piece', availability: 'In Stock' }
]
[
  { name: 'Bread', price: '$15 / piece', availability: 'In Stock' },
  { name: 'Apple Pie', price: '$20 / piece', availability: 'In Stock' }
]
[
  { name: 'Bread', price: '$15 / piece', availability: 'In Stock' },
  { name: 'Apple Pie', price: '$20 / piece', availability: 'In Stock' }
]
const puppeteer = require("puppeteer");
const createCsvWriter = require("csv-writer").createObjectCsvWriter;

(async () => {
  const browser = await puppeteer.launch({
    headless: false,
    IgnoreHTTPSErrors: true,
  });
  const page = await browser.newPage();
  await page.setViewport({ width: 1366, height: 820 });

  await page.goto("https://www.pabson.org/#!/School-locator");
  const selectOptions = await page.$$eval(
    "select#ddlState > option",
    (options) => {
      return options.map(function (option) {
        return { option: option.innerHTML, value: option.value };
      });
    }
  );
  async function scrape_and_save(item) {
    // let item = obj;
    await page.select("#ddlState", item.value);
    try {
      await page.waitForSelector("div.count-box-info");
      const school_array = await page.evaluate((x) => {
        let school = [];
        let school_list = document.querySelectorAll("div.count-box-info");
        school_list.forEach((item) => {
          school.push({
            name: item.getElementsByTagName("h4")[0].innerText,
            phone: item.getElementsByTagName("p")[0].innerText,
            email: item.getElementsByTagName("p")[1].innerText,
          });
        });
        return school;
      });

      let csvWriter = createCsvWriter({
        path: "school_" + item.option + ".csv",
        header: [
          { id: "name", title: "NAME" },
          { id: "phone", title: "PHONE" },
          { id: "email", title: "EMAIL" },
        ],
      });

      csvWriter
        .writeRecords(school_array) // returns a promise
        .then(() => {
          console.log("...Done");
        });
    } catch (e) {
      console.log(e);
    }
  }
  for (item of selectOptions) {
    await scrape_and_save(item);
  }
  await browser.close();
})();