【问题标题】:How to scrape date from iframe tag with with puppeteer如何使用 puppeteer 从 iframe 标签中抓取日期
【发布时间】:2019-12-01 21:03:02
【问题描述】:

我尝试从 iframe/frame 标记中抓取一些数据,但我被 puppeteer 的代码卡住了。我是新手,所以请多多包涵。这是该网站的链接。当我点击时在那里在第一帧的名称中,我再次在女巫的第二帧中获得了一些数据,我可以单击并在第三帧中获取数据。 在代码中,我尝试循环真正的第一帧以获取第二帧和第三帧的所有数据。

感谢您的任何提示。

我已经运行了这个命令: document.querySelector("正文 > 表单 > 字体 > 选择 > 选项") 在控制台中,但我找不到在 puppeteer 中运行它的方法。

const puppeteer = require("puppeteer");

(async () => {

    const browser = await puppeteer.launch();

    const page = await browser.newPage();
    await page.goto('');

    const iframeParagraph = await page.evaluate(() => {

        const iframe = document.getElementsByName("stanga");

        // grab iframe's document object
        const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;

        const iframeP = iframeDoc.getElementsByName("fmtstatii");

        return iframeP.innerHTML;
    });

    console.log(iframeParagraph); 

    await browser.close();

})();

const puppeteer = require('puppeteer');

let scrape = async () => {
    const browser = await puppeteer.launch({headless: false});
    const page = await browser.newPage();

    await page.goto('');
    await page.click('document.querySelector("body > form > font > select")');
    await page.waitFor(1000);

    const result = await page.evaluate(() => {
        let statie = document.querySelector('document.querySelector("body > form > font > select > option")').innerText;

        return {
            statie
        }

    });

    browser.close();
    return result;
};

scrape().then((value) => {
    console.log(value); // Success!
});

这是我得到的错误:

[(node:13308) UnhandledPromiseRejectionWarning: Error: Evaluation failed: DOMException: Failed to execute 'querySelector' on 'Document': 'document.querySelector("body > form > font > select")' is not a
valid selector.
    at __puppeteer_evaluation_script__:1:33
    at ExecutionContext._evaluateInternal (D:\Zero\ratt_scrap\node_modules\puppeteer\lib\ExecutionContext.js:122:13)
    at process._tickCallback (internal/process/next_tick.js:68:7)
  -- ASYNC --
    at ExecutionContext.<anonymous> (D:\Zero\ratt_scrap\node_modules\puppeteer\lib\helper.js:111:15)
    at ElementHandle.$ (D:\Zero\ratt_scrap\node_modules\puppeteer\lib\JSHandle.js:395:50)
    at ElementHandle.<anonymous> (D:\Zero\ratt_scrap\node_modules\puppeteer\lib\helper.js:112:23)
    at DOMWorld.$ (D:\Zero\ratt_scrap\node_modules\puppeteer\lib\DOMWorld.js:121:34)
    at process._tickCallback (internal/process/next_tick.js:68:7)
  -- ASYNC --
    at Frame.<anonymous> (D:\Zero\ratt_scrap\node_modules\puppeteer\lib\helper.js:111:15)
    at Page.click (D:\Zero\ratt_scrap\node_modules\puppeteer\lib\Page.js:986:29)
    at scrape (D:\Zero\ratt_scrap\scrape.js:23:16)
    at process._tickCallback (internal/process/next_tick.js:68:7)
(node:13308) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:13308) \[DEP0018\] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.]

【问题讨论】:

    标签: javascript puppeteer


    【解决方案1】:

    你犯了几个错误:

    1. 您应该与Frame 而不是Page 对象进行交互。

      const frame = await page.frames().find(frame => frame.name() === 'stanga'); // Find the right frame.
      
    2. click() 方法需要selector &lt;string&gt;,因此您无需在click() 方法中添加document.querySelector

      await frame.click('body > form > font > select');
      
    3. 要获取所有innerText,您必须遍历元素。

    4. 别忘了添加await。你错过了close 方法。

      await browser.close();
      

    解决方案:

    const puppeteer = require('puppeteer');
    
    let scrape = async () => {
    const browser = await puppeteer.launch({headless: false});
    const page = await browser.newPage();
    
    await page.goto('http://ratt.ro/txt');
    const frame = await page.frames().find(frame => frame.name() === 'stanga');
    await frame.click('body > form > font > select');
    await page.waitFor(1000);
    
    
    const optionsResult = await frame.$$eval('body > form > font > select > option', (options) => {
        const result = options.map(option => option.innerText);
    
        return result;
    });
    
    await browser.close();
    
    return optionsResult;
    };
    
    scrape().then((value) => {
      console.log(value); // Success!
    });
    

    【讨论】:

    • 非常感谢!我这几天一直在寻找解决方案。你能不能给我推荐一些链接、书籍或教程,以更好地了解如何更好地在 JavaScript、Node 和傀儡师?
    • 嗨@Shiva200178!如果您也将此答案标记为有用,那就太好了。我强烈建议阅读 Node nodejs.org/dist/latest-v10.x/docs/api 和 puppeteer pptr.dev 的官方文档。这是 javascript javascript.info/intro 的最佳在线书籍。希望对你有帮助!
    • 嗨耶夫亨。我标记为有用,但我仍然卡住,因为此代码从第一帧中选择所有数据。我想要的是第一帧中的每个条目都进入第 2 帧以选择一个选项,然后从那里进入第 3 帧然后获取所有数据(frame1 + frame 2 + frame 3)。我想为第 2 帧 > 第 1 帧的所有选项输出第 3 帧的所有数据。
    • 嘿@Shiva200178!抱歉回复晚了,我已经在您的问题中修复了我们的脚本。希望对您有所帮助。
    • 嗨 Yeven。没关系,不要着急,因为我才刚刚开始,我已经开始学习 React 和 Node,我想制作一个应用程序来为我的项目实时显示数据,所以是不急。现在我将等待将其保存到文件或将其作为 API 发布到网站上以从那里访问它,然后从那里开始构建我的应用程序。
    猜你喜欢
    • 2021-02-09
    • 2021-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-06
    • 2021-10-18
    • 2020-12-02
    • 2023-03-16
    相关资源
    最近更新 更多