簡體   English   中英

如何將大量文本發送到 contenteditable="true" 元素中?

[英]How do I send a large amount of text into a contenteditable="true" element?

更新:

經過更多研究,我意識到我可以以更具體的方式提出這個問題:如何將大量文本發送到contenteditable="true"元素中?


我正在使用一個具有 API 的網站,但它沒有任何可以編輯內容的端點。 這個 API 限制阻止了我的發布過程自動化。 作為一種解決方法,我嘗試使用無頭瀏覽器自動執行任務。

其中一項任務涉及在富文本編輯器中編輯內容。 這個富文本編輯器沒有任何input元素,所以這不像改變某些東西的值那么簡單。 HTML 看起來類似於:

在此處輸入圖片說明

您可以在此處查看此富文本編輯器的來源: https : //www.slatejs.org/examples/richtext

我已經嘗試使用一些 puppeteer 代碼(我不在乎這個答案的解決方案是否是 puppeteer)來解決這個問題。 它有效,但太慢了:我有 30k 的文本要發送給編輯器,所以await page.keyboard.type(stdin, {delay: 0}); 運行需要十多分鍾。 這是我的代碼:

export const edit = async () => {
  const browser = await launch({ headless: false });
  const page = await browser.newPage();
  try {
    await page.setUserAgent(
      'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:93.0) Gecko/20100101 Firefox/93.0'
    );
    await page.goto('https://www.slatejs.org/examples/richtext');
    await page.waitForSelector('[data-slate-string="true"]');
    await page.click('[data-slate-string="true"]');
 
    // select all
    await page.keyboard.down('Control');
    await page.keyboard.press('a');
    await page.keyboard.up('Control');

    // clear everything in the rich text editor
    await page.keyboard.press('Backspace');

    // type in new content
    await page.keyboard.type(aLargeAmountOfText, {delay: 0}); // this takes over 10 minutes!  
  } finally {
    await page.screenshot({ path: 'example.png' });
    await browser.close();
  }
};

工作(理論上)有一兩件事,是自動復制和粘貼文本到編輯器。 我真的不想走這條路,因為我在釋放時傾向於做其他事情。 如果我的腳本在運行時修改了我的剪貼板(或者我修改了它),它可能會產生不可預測的結果。

將大量文本發送到沒有input元素的富文本編輯器的最快方法是什么? 我不在乎使用什么自動化工具(如果可能,我更喜歡 node.js),或者我必須使用什么技巧,只要我能弄清楚如何回答這個問題。

你可以用page.$eval試試:

export const edit = async () => {
  const browser = await launch({ headless: false });
  const page = await browser.newPage();
  try {
    await page.setUserAgent(
      'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:93.0) Gecko/20100101 Firefox/93.0'
    );
    await page.goto('https://www.slatejs.org/examples/richtext');
    await page.waitForSelector('[contenteditable="true"]');
    await page.$eval('[contenteditable="true"]', (e) => e.textContent = aLargeAmountOfText);
  } finally {
    await page.screenshot({ path: 'example.png' });
    await browser.close();
  }
};

OK,這是那么很難搞清楚。 這里是:

    await page.goto(url);

    const richTextEditorSelector = '[contenteditable="true"]';
    await page.waitForSelector(richTextEditorSelector);
    await page.focus(richTextEditorSelector);

    // select all
    await page.evaluate(() => {
      return Promise.resolve(document.execCommand('selectAll'));
    });

    const pasteReplacementText = `
const dataTransfer = new DataTransfer();

function dispatchPaste(target) {
  // this may be 'text/html' if it's required
  dataTransfer.setData('text/plain', \`${replacementText}\`);

  target.dispatchEvent(
    new ClipboardEvent('paste', {
      clipboardData: dataTransfer,

      // need these for the event to reach Draft paste handler
      bubbles: true,
      cancelable: true
    })
  );

  // clear DataTransfer Data
  dataTransfer.clearData();
}

dispatchPaste(document.querySelectorAll('${richTextEditorSelector}')[0]);
`;

    console.log(`replacementText=

${pasteReplacementText}`); // leaving this here because it may help others troubleshoot
    await page.evaluate(pasteReplacementText);

那個復雜的字符串使編輯器認為發生了粘貼。 您提供數據。

以下是我曾經提出的一些來源:

  1. https://stackoverflow.com/a/63643176/61624
  2. https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Editable_content
  3. https://developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent
  4. https://github.com/puppeteer/puppeteer/blob/main/docs/api.md#pageevaluatepagefunction-args
  5. https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM