【问题标题】:How to call function after everything is resolved?一切解决后如何调用函数?
【发布时间】:2019-10-06 06:09:05
【问题描述】:

我正在使用 puppeteer 从网站中提取数据。我的问题是在获取所有内容后关闭浏览器。

请帮帮我 :) 这是 GraphQL 的解析器函数。


const Somesite = async ({ ticker }) => {
    const browser = await puppeteer.launch({ headless: false});
    const page = await browser.newPage();
    await page.goto('https://Somesite.com/quote.ashx?t=' + ticker);
    let result = {
        ticker,
        market_cap: async () => {
            return await fetch_data_with_xpath(page, { ticker, xpath: "/html/body/table[3]/tbody/tr[1]/td/table/tbody/tr[7]/td/table/tbody/tr[2]/td[2]/b" })
        },
        float: async () => {
            return await fetch_data_with_xpath(page, { ticker, xpath: "/html/body/table[3]/tbody/tr[1]/td/table/tbody/tr[7]/td/table/tbody/tr[2]/td[10]/b" })
        },
        insider_own: async () => {
            return await fetch_data_with_xpath(page, { ticker, xpath: "/html/body/table[3]/tbody/tr[1]/td/table/tbody/tr[7]/td/table/tbody/tr[1]/td[8]/b" })
        },
        short_float: async () => {
            return await fetch_data_with_xpath(page, { ticker, xpath: "/html/body/table[3]/tbody/tr[1]/td/table/tbody/tr[7]/td/table/tbody/tr[3]/td[10]/b" })
        },
        date: async () => {
            return moment().format("MM/DD/YYYY");
        },
        cash_per_share: async () => {
            return await fetch_data_with_xpath(page, { ticker, xpath: "/html/body/table[3]/tbody/tr[1]/td/table/tbody/tr[7]/td/table/tbody/tr[6]/td[2]/b" })
        },
        dept_equity: async () => {
            return await fetch_data_with_xpath(page, { ticker, xpath: "/html/body/table[3]/tbody/tr[1]/td/table/tbody/tr[7]/td/table/tbody/tr[10]/td[4]/b/span" })
        },
        browser : async () => {
            return browser.close()
        }
    };


    return result;
};

const fetch_data_with_xpath = async (page, { ticker, xpath }) => {
    const element = await page.$x(xpath);
    let text = "";
    if (!!element) {
        text = await page.evaluate(element => element.textContent, element[0]);
    }
    return text;
}

我尝试为每个数据元素打开单独的浏览器,但这不是很有效并且很快就会达到限制。

我不能让浏览器保持打开状态,这不是一个选项。 当我在定义result 后触发browser.close 时,浏览器过早关闭并且没有获取数据。

【问题讨论】:

    标签: node.js asynchronous ecmascript-6 graphql puppeteer


    【解决方案1】:

    首先从你的对象中删除browser.close(),因为对象中的属性是无序的,它不会起作用。

    假设对象上的所有元素都是一个函数,我们可以利用for..ofasync..await

    async function getResult() {
     // hold all of our related functions
     let resultFunctions = {
      ticker,
      market_cap: async () => {
       return fetch_data_with_xpath(page, {
        ticker,
        xpath: "/html/body/table[3]/tbody/tr[1]/td/table/tbody/tr[7]/td/table/tbody/tr[2]/td[2]/b"
       })
      }
     };
    
     let result = {}
     // run all functions inside the object
     for (let [key, fn] of Object.entries(resultFunctions)) {
      if (typeof fn === 'function') {
       result[key] = await fn()
      }
    
      // if it's not a function, 
      // then it's "Probably" a string according to our schema above
      if (typeof fn === 'string') result[key] = fn;
     }
     return result;
    }
    
    const result = await getResult()
    await browser.close()
    

    【讨论】:

      猜你喜欢
      • 2023-03-28
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      • 2011-03-01
      • 2021-10-17
      • 1970-01-01
      • 1970-01-01
      • 2021-09-26
      相关资源
      最近更新 更多