Как вызвать функцию после того, как все решено? - PullRequest
0 голосов
/ 19 мая 2019

Я использую кукловодов для извлечения данных с сайтов.Моя проблема с закрытием браузера после того, как все получено.

Пожалуйста, помогите мне :) Это функция распознавания для 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;
}

Я пытался открыть отдельный браузер для каждого элемента данных, но это не очень эффективно и быстродостигните предела.

Я не могу оставить браузер открытым, это не вариант.Когда я запускаю browser.close после определения result, браузер преждевременно закрывается и данные не извлекаются.

1 Ответ

1 голос
/ 19 мая 2019

Сначала удалите browser.close() изнутри вашего объекта, так как свойства в объектах не упорядочены, это не сработает.

Предполагая, что все элементы объекта являются функцией, мы можем воспользоваться for..of с async..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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...