更新:
經過更多研究,我意識到我可以以更具體的方式提出這個問題:如何將大量文本發送到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();
}
};
一件事會作業(理論上),是自動復制和粘貼文本到編輯器。我真的不想走這條路,因為我在釋放時傾向于做其他事情。如果我的腳本在運行時修改了我的剪貼板(或者我修改了它),它可能會產生不可預測的結果。
What's the quickest way of sending a large amount of text to a rich text editor that has no input elements? I don't care what automation tool is used (I'd prefer node.js, if possible), or what tricks I have to use, so long as I can figure out how to answer this question.
uj5u.com熱心網友回復:
你可以用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();
}
};
uj5u.com熱心網友回復:
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);
那個復雜的字串使編輯器認為發生了粘貼。您提供資料。
以下是我曾經提出的一些來源:
- https://stackoverflow.com/a/63643176/61624
- https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Editable_content
- https://developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent
- https://github.com/puppeteer/puppeteer/blob/main/docs/api.md#pageevaluatepagefunction-args
- https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/329940.html
標籤:javascript node.js selenium puppeteer contenteditable
