Automatisieren der Erstellung und Übermittlung von LeetCode-Lösungsbeiträgen: Herausforderungen mit DOM-Manipulation, Cl
Posted: 05 Jan 2025, 09:58
Ich erstelle eine Chrome-Erweiterung, um die Erstellung von Lösungsbeiträgen auf LeetCode zu automatisieren, nachdem eine Lösung angenommen wurde. Das Ziel ist: 1. Öffnen Sie die Seite „Lösung posten“.2. Füllen Sie das Eingabefeld „Titel“ automatisch mit einer benutzerdefinierten Zeichenfolge.3. Füllen Sie den Monaco-Editor mit einer formatierten Lösungsvorlage.
Das Setup
1. Umgebung:
• Chrome-Erweiterung (Manifest V3) mit Plasmo Framework.
• Die Erweiterung enthält:
• Ein Hintergrundskript für die Tab-Erstellung und Nachrichtenübermittlung.
• Ein Inhaltsskript für DOM-Interaktion auf der Seite „Lösung veröffentlichen“.
2. Ansatz:
• Das Hintergrundskript öffnet die Lösungsbeitragsseite und sendet eine Nachricht mit der einzufügenden Vorlage an das Inhaltsskript.
• Das Inhaltsskript übernimmt die DOM-Manipulation, einschließlich:
• Eingeben von Text in das Eingabefeld.
• Kopieren und Einfügen von Inhalten in den Monaco-Editor.
Herausforderungen und was wir versucht haben
Das Eingabefeld wird manchmal teilweise aktualisiert (z. B. wird „Automatisierter Titel“ zu „tomierter Titel“) oder überhaupt nicht aktualisiert.
Versuche:
1. Wert direkt festlegen:
•Ergebnis: Funktioniert manchmal, aktualisiert das Feld jedoch häufig nicht ordnungsgemäß oder löst Listener aus, die den Wert zurücksetzen.
2. Tastendruckereignisse simulieren :
•Ergebnis: Dies funktioniert besser, führt aber gelegentlich zu unvollständigem Text. Es scheint, dass externe Ereignis-Listener oder DOM-Updates den Prozess stören.
•Ergebnis: Die Zwischenablage-API schlägt mit einem NotAllowedError fehl, sofern sie nicht durch eine Benutzerinteraktion (z. B. Klicken auf eine Schaltfläche) ausgelöst wird.
Der Monaco-Editor verlässt sich auf seine monaco.editor.getModels()[ 0] API, auf die nicht direkt zugegriffen werden kann das Inhaltsskript, da das Skript in einem anderen Ausführungskontext ausgeführt wird.
Versuche:
1. Verwenden der Monaco-API:
•Ergebnis: Funktioniert perfekt in der Browserkonsole, schlägt jedoch im Inhaltsskript fehl, da Monaco nicht definiert ist.
2. Code in die Hauptwelt einfügen:
• Eine Funktion mit chrome.scripting.executeScript eingefügt:
•Ergebnis: Monaco ist in der Hauptwelt aufgrund von CSP-Einschränkungen undefiniert.
Gelegentlich löst das Festlegen des Titels LeetCodes Backend-Anfragen aus, die zu 429 Too Many Requests führen.
Versuche:
1. Verzögerungen zwischen Aktionen hinzugefügt.
2. Reduzierte unnötige Ereignisauslösung.
3. Entprellen wurde verwendet, um schnelle Interaktionen zu vermeiden.
•Ergebnis: Die Ratenbegrenzung bleibt bestehen, wenn Aktionen zu häufig sind.
Codeausschnitte
Hintergrundskript:
Inhaltsskript:
Wobei wir Hilfe benötigen:
1. Wie können wir den Wert des Titeleingabefelds zuverlässig festlegen (z. B. „Automatisierter Titel“) und gleichzeitig Teilaktualisierungen oder Zurücksetzungen vermeiden?
2. Wie kann ich in einer Chrome-Erweiterung am besten auf den Monaco-Editor zugreifen und ihn bearbeiten?
3. Wie können wir vermeiden, dass die Geschwindigkeitsbegrenzung von LeetCode (429 Fehler) während der DOM-Manipulation ausgelöst wird?
4. Gibt es andere robuste Methoden, um Benutzerinteraktionen (Eingabe, Einfügen) programmgesteuert zu simulieren?
Was wir versucht haben:
• Direkte DOM-Manipulation (Wert, setAttribute).
• Simulieren von Tastenanschlägen mit KeyboardEvent.
• Kopieren in die Zwischenablage und Einfügen mit ClipboardEvent.
• Einfügen von Code in die Hauptwelt, um auf die Monaco-API zuzugreifen.
Trotz allem diese Trotz aller Versuche habe ich immer noch Probleme mit der Zuverlässigkeit und Kompatibilität. Für Ratschläge, Einblicke oder alternative Ansätze wäre ich sehr dankbar!
Das Setup
1. Umgebung:
• Chrome-Erweiterung (Manifest V3) mit Plasmo Framework.
• Die Erweiterung enthält:
• Ein Hintergrundskript für die Tab-Erstellung und Nachrichtenübermittlung.
• Ein Inhaltsskript für DOM-Interaktion auf der Seite „Lösung veröffentlichen“.
2. Ansatz:
• Das Hintergrundskript öffnet die Lösungsbeitragsseite und sendet eine Nachricht mit der einzufügenden Vorlage an das Inhaltsskript.
• Das Inhaltsskript übernimmt die DOM-Manipulation, einschließlich:
• Eingeben von Text in das Eingabefeld.
• Kopieren und Einfügen von Inhalten in den Monaco-Editor.
Herausforderungen und was wir versucht haben
- Das Titeleingabefeld füllen
Das Eingabefeld wird manchmal teilweise aktualisiert (z. B. wird „Automatisierter Titel“ zu „tomierter Titel“) oder überhaupt nicht aktualisiert.
Versuche:
1. Wert direkt festlegen:
Code: Select all
inputElement.value = "Automated Title";
inputElement.dispatchEvent(new Event("input", { bubbles: true }));
inputElement.dispatchEvent(new Event("change", { bubbles: true }));
2. Tastendruckereignisse simulieren :
Code: Select all
for (const char of text) {
inputElement.value += char;
inputElement.dispatchEvent(new KeyboardEvent("keydown", { key: char }));
inputElement.dispatchEvent(new KeyboardEvent("keypress", { key: char }));
inputElement.dispatchEvent(new KeyboardEvent("keyup", { key: char }));
}
- Text in die Zwischenablage kopieren und einfügen:
Code: Select all
await navigator.clipboard.writeText("Automated Title");
const pasteEvent = new ClipboardEvent("paste", { bubbles: true });
inputElement.dispatchEvent(pasteEvent);
- Auffüllen des Monaco-Editors
Der Monaco-Editor verlässt sich auf seine monaco.editor.getModels()[ 0] API, auf die nicht direkt zugegriffen werden kann das Inhaltsskript, da das Skript in einem anderen Ausführungskontext ausgeführt wird.
Versuche:
1. Verwenden der Monaco-API:
Code: Select all
const model = monaco.editor.getModels()[0];
model.setValue(template);
2. Code in die Hauptwelt einfügen:
• Eine Funktion mit chrome.scripting.executeScript eingefügt:
Code: Select all
chrome.scripting.executeScript({
target: { tabId: tab.id },
world: "MAIN",
func: pasteTemplateIntoPage,
args: [template],
});
- Handhabung Ratenbegrenzung (429 Fehler)
Gelegentlich löst das Festlegen des Titels LeetCodes Backend-Anfragen aus, die zu 429 Too Many Requests führen.
Versuche:
1. Verzögerungen zwischen Aktionen hinzugefügt.
2. Reduzierte unnötige Ereignisauslösung.
3. Entprellen wurde verwendet, um schnelle Interaktionen zu vermeiden.
•Ergebnis: Die Ratenbegrenzung bleibt bestehen, wenn Aktionen zu häufig sind.
Codeausschnitte
Hintergrundskript:
Code: Select all
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.action === "openSubmissionPage") {
chrome.tabs.create({ url: message.url, active: true }, (tab) => {
if (tab?.id) {
chrome.tabs.onUpdated.addListener(function listener(tabId, changeInfo) {
if (tabId === tab.id && changeInfo.status === "complete") {
chrome.tabs.onUpdated.removeListener(listener);
chrome.tabs.sendMessage(tab.id, { action: "pasteTemplate", template: message.template });
}
});
}
});
Code: Select all
async function typeIntoInputField(selector, text) {
const inputElement = document.querySelector(selector);
if (!inputElement) return;
inputElement.value = "";
for (const char of text) {
inputElement.value += char;
inputElement.dispatchEvent(new KeyboardEvent("keydown", { key: char }));
inputElement.dispatchEvent(new KeyboardEvent("keypress", { key: char }));
inputElement.dispatchEvent(new KeyboardEvent("keyup", { key: char }));
await new Promise((r) => setTimeout(r, 100));
}
}
1. Wie können wir den Wert des Titeleingabefelds zuverlässig festlegen (z. B. „Automatisierter Titel“) und gleichzeitig Teilaktualisierungen oder Zurücksetzungen vermeiden?
2. Wie kann ich in einer Chrome-Erweiterung am besten auf den Monaco-Editor zugreifen und ihn bearbeiten?
3. Wie können wir vermeiden, dass die Geschwindigkeitsbegrenzung von LeetCode (429 Fehler) während der DOM-Manipulation ausgelöst wird?
4. Gibt es andere robuste Methoden, um Benutzerinteraktionen (Eingabe, Einfügen) programmgesteuert zu simulieren?
Was wir versucht haben:
• Direkte DOM-Manipulation (Wert, setAttribute).
• Simulieren von Tastenanschlägen mit KeyboardEvent.
• Kopieren in die Zwischenablage und Einfügen mit ClipboardEvent.
• Einfügen von Code in die Hauptwelt, um auf die Monaco-API zuzugreifen.
Trotz allem diese Trotz aller Versuche habe ich immer noch Probleme mit der Zuverlässigkeit und Kompatibilität. Für Ratschläge, Einblicke oder alternative Ansätze wäre ich sehr dankbar!