diff --git a/README.md b/README.md index f56e4564..48b1bcc1 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@

Maxun lets you train a robot in 2 minutes and scrape the web on auto-pilot. Web data extraction doesn't get easier than this! +
Maxun is the open-source alternative to BrowseAI, Octoparse and likes.

diff --git a/maxun-core/src/interpret.ts b/maxun-core/src/interpret.ts index d87e4bc2..a34777d8 100644 --- a/maxun-core/src/interpret.ts +++ b/maxun-core/src/interpret.ts @@ -1187,7 +1187,7 @@ export default class Interpreter extends EventEmitter { }).catch(e => { throw e; }), - button.click() + page.locator(workingSelector).first().click() ]); debugLog("Navigation successful after regular click"); await page.waitForTimeout(2000); @@ -1202,17 +1202,17 @@ export default class Interpreter extends EventEmitter { }).catch(e => { throw e; }), - button.dispatchEvent('click') + page.locator(workingSelector).first().dispatchEvent('click') ]); debugLog("Navigation successful after dispatch event"); await page.waitForTimeout(2000); paginationSuccess = true; } catch (dispatchNavError) { try { - await button.click(); + await page.locator(workingSelector).first().click(); await page.waitForTimeout(2000); } catch (clickError) { - await button.dispatchEvent('click'); + await page.locator(workingSelector).first().dispatchEvent('click'); await page.waitForTimeout(2000); } } diff --git a/server/src/workflow-management/classes/Interpreter.ts b/server/src/workflow-management/classes/Interpreter.ts index 2ab7a319..e65bf9af 100644 --- a/server/src/workflow-management/classes/Interpreter.ts +++ b/server/src/workflow-management/classes/Interpreter.ts @@ -550,22 +550,17 @@ export class WorkflowInterpreter { }, serializableCallback: async (data: any) => { try { - if (!data || typeof data !== "object") return; + if (!this.currentActionType || !this.currentActionName) return; - if (!this.currentActionType && Array.isArray(data) && data.length > 0) { - const first = data[0]; - if (first && Object.keys(first).some(k => k.toLowerCase().includes("label") || k.toLowerCase().includes("text"))) { - this.currentActionType = "scrapeSchema"; - } - } + let typeKey = this.currentActionType; + let actionName = this.currentActionName; - let typeKey = this.currentActionType || "unknown"; - - if (this.currentActionType === "scrapeList") { - typeKey = "scrapeList"; - } else if (this.currentActionType === "scrapeSchema") { - typeKey = "scrapeSchema"; - } + let subtree = + typeKey === "scrapeList" + ? data?.scrapeList + : typeKey === "scrapeSchema" + ? data?.scrapeSchema + : null; if (typeKey === "scrapeList" && data.scrapeList) { data = data.scrapeList; @@ -617,7 +612,7 @@ export class WorkflowInterpreter { data: flattened, }); } catch (err: any) { - logger.log('error', `serializableCallback handler failed: ${err.message}`); + logger.log("error", `serializableCallback failed: ${err.message}`); } }, binaryCallback: async (payload: { name: string; data: Buffer; mimeType: string }) => { diff --git a/src/components/robot/pages/RobotSettingsPage.tsx b/src/components/robot/pages/RobotSettingsPage.tsx index 11832935..cb456e3d 100644 --- a/src/components/robot/pages/RobotSettingsPage.tsx +++ b/src/components/robot/pages/RobotSettingsPage.tsx @@ -152,20 +152,36 @@ export const RobotSettingsPage = ({ handleStart }: RobotSettingsProps) => { }} style={{ marginBottom: "20px" }} /> - {robot.recording.workflow?.[0]?.what?.[0]?.args?.[0]?.limit !== - undefined && ( - - )} + {(() => { + let listCounter = 1; + + return robot.recording.workflow.flatMap((wf, wfIndex) => + wf.what.flatMap((action, actionIndex) => { + const argsWithLimit = action.args?.filter( + (arg: any) => arg && typeof arg === "object" && arg.limit !== undefined + ); + + if (!argsWithLimit?.length) return []; + + return argsWithLimit.map((arg, limitIndex) => { + const labelName = action.name || `List ${listCounter++}`; + return ( + + ); + }); + }) + ); + })()} +