Craiyon Crawler avatar
Craiyon Crawler
Deprecated
View all Actors
This Actor is deprecated

This Actor is unavailable because the developer has decided to deprecate it. Would you like to try a similar Actor instead?

See alternative Actors
Craiyon Crawler

Craiyon Crawler

hamza.alwan/craiyon-crawler

Get links to images generated by Craiyon (formerly DALL·E mini) - an AI model that can draw images from any text prompt. Input any combination of text and get links to AI-generated images created by the engine. Export URLs of these images into a database in formats such as HTML, JSON, CSV, Excel.

.dockerignore

1# configurations
2.idea
3
4# crawlee and apify storage folders
5apify_storage
6crawlee_storage
7storage
8
9# installed files
10node_modules

.editorconfig

1root = true
2
3[*]
4indent_style = space
5indent_size = 4
6charset = utf-8
7trim_trailing_whitespace = true
8insert_final_newline = true
9end_of_line = lf

.eslintrc

1{
2    "extends": "@apify",
3    "root": true
4}

.gitignore

1# This file tells Git which files shouldn't be added to source control
2
3.idea
4dist
5node_modules
6apify_storage
7crawlee_storage
8storage
9.DS_Store
10INPUT.json

Dockerfile

1# Specify the base Docker image. You can read more about
2# the available images at https://crawlee.dev/docs/guides/docker-images
3# You can also use any other image from Docker Hub.
4FROM apify/actor-node:16 AS builder
5
6# Copy just package.json and package-lock.json
7# to speed up the build using Docker layer cache.
8COPY package*.json ./
9
10# Install all dependencies. Don't audit to speed up the installation.
11RUN npm install --include=dev --audit=false
12
13# Next, copy the source files using the user set
14# in the base image.
15COPY . ./
16
17# Install all dependencies and build the project.
18# Don't audit to speed up the installation.
19RUN npm run build
20
21# Create final image
22FROM apify/actor-node:16
23
24# Copy only built JS files from builder image
25COPY --from=builder /usr/src/app/dist ./dist
26
27# Copy just package.json and package-lock.json
28# to speed up the build using Docker layer cache.
29COPY package*.json ./
30
31# Install NPM packages, skip optional and development dependencies to
32# keep the image small. Avoid logging too much and print the dependency
33# tree for debugging
34RUN npm --quiet set progress=false \
35    && npm install --omit=dev --omit=optional \
36    && echo "Installed NPM packages:" \
37    && (npm list --omit=dev --all || true) \
38    && echo "Node.js version:" \
39    && node --version \
40    && echo "NPM version:" \
41    && npm --version
42
43# Next, copy the remaining files and directories with the source code.
44# Since we do this after NPM install, quick build will be really fast
45# for most source file changes.
46COPY . ./
47
48
49# Run the image.
50CMD npm run start:prod --silent

INPUT_SCHEMA.json

1{
2    "title": "Craiyon images crawler input",
3    "description": "Text which you would Craiyon to generate images for, like `Cats`, `Wood buildings`",
4    "type": "object",
5    "schemaVersion": 1,
6    "properties": {
7        "searchStrings": {
8            "title": "Search Text",
9            "type": "array",
10            "description": "Enter a text of what images you would like Craiyon to generate, you can add multiple values.",
11            "prefill": [ "Wood Sword"],
12            "editor": "stringList",
13            "uniqueItems": true,
14            "minItems": 1
15        }
16    },
17    "required": ["searchStrings"]
18}

apify.json

1{
2	"name": "craiyon-crawler",
3	"version": "1.0",
4	"buildTag": "latest",
5	"env": null
6}

package.json

1{
2    "name": "craiyon-crawler",
3    "version": "0.0.1",
4    "type": "module",
5    "description": "Craiyon images generator",
6    "dependencies": {
7        "apify": "^3.1.0",
8        "crawlee": "^3.1.0",
9        "uuid": "^9.0.0"
10    },
11    "devDependencies": {
12        "@apify/tsconfig": "^0.1.0",
13        "@types/uuid": "^8.3.4",
14        "ts-node": "^10.8.0",
15        "typescript": "^4.7.4",
16        "tsc-silent": "^1.2.2"
17    },
18    "scripts": {
19        "start": "npm run start:dev",
20        "start:prod": "node dist/main.js",
21        "start:dev": "ts-node-esm -T src/main.ts",
22        "build": "tsc-silent -p tsconfig.json --suppress @",
23        "test": "echo \"Error: oops, the actor has no tests yet, sad!\" && exit 1"
24    },
25    "author": "Hamza Alwan",
26    "license": "ISC"
27}

tsconfig.json

1{
2    "extends": "@apify/tsconfig",
3    "compilerOptions": {
4        "module": "ES2022",
5        "target": "ES2022",
6        "outDir": "dist",
7        "noUnusedLocals": false,
8        "lib": ["DOM"]
9    },
10    "include": [
11        "./src/**/*"
12    ]
13}

src/main.ts

1// For more information, see https://crawlee.dev/
2import { HttpCrawler, KeyValueStore, log } from "crawlee";
3import { Actor } from "apify";
4
5import { router } from "./routes.js";
6
7await Actor.init();
8
9interface InputSchema {
10    debug?: boolean;
11    searchStrings: string[];
12}
13
14let debug, searchStrings;
15
16const input = await KeyValueStore.getInput<InputSchema>();
17
18debug = input?.debug;
19searchStrings = input?.searchStrings;
20
21// Get input from Apify console
22if (!searchStrings) {
23    const input = await Actor.getInput<InputSchema>();
24
25    debug = input?.debug;
26    searchStrings = input?.searchStrings;
27}
28
29if (!(Array.isArray(searchStrings) && searchStrings.length > 0)) {
30    throw new Error('Wrong INPUT: searchStrings has to be an array with at least one text');
31}
32
33if (debug) {
34    log.setLevel(log.LEVELS.DEBUG);
35}
36
37const proxyConfiguration = await Actor.createProxyConfiguration({
38    useApifyProxy: true,
39});
40
41const crawler = new HttpCrawler({
42    proxyConfiguration,
43    navigationTimeoutSecs: 60 * 5, // Takes a while to generate images
44    requestHandler: router,
45    errorHandler: async ({ response }) => {
46        log.error(`Response status is: ${response?.statusCode} msg: ${response?.statusMessage}`);
47    },
48});
49
50await crawler.run(
51    searchStrings.map(searchString => {
52        log.info(`Generating images for ${searchString}...`);
53
54        return {
55            url: "https://backend.craiyon.com/generate",
56            method: "POST",
57            payload: JSON.stringify({ prompt: searchString.toLowerCase() }),
58            headers: {
59                "content-type": "application/json",
60            },
61            useExtendedUniqueKey: true,
62            userData: {
63                searchString
64            }
65        }
66    })
67);
68
69await Actor.exit();

src/routes.ts

1import { KeyValueStore, Dataset, createHttpRouter } from "crawlee";
2import { v4 as uuid } from "uuid";
3
4export const router = createHttpRouter();
5
6router.addDefaultHandler(async ({ request, log, json }) => {
7    const { userData: { searchString } } = request;
8
9    if (!json || !json?.images || !json?.images?.length) {
10        throw new Error (`Couldn't generate images`);
11    }
12
13    const { images } = json;
14
15    log.info(`Successfully generated ${images.length} images for ${searchString}`);
16
17    const keyValueStore = await KeyValueStore.open();
18
19    for (const image of images) {
20        const key = uuid();
21        const imageBuffer = Buffer.from(image, "base64");
22
23        await keyValueStore.setValue(key, imageBuffer, {
24            contentType: "image/png",
25        });
26
27        const imageUrl = `https://api.apify.com/v2/key-value-stores/${keyValueStore.id}/records/${key}`;
28
29        await Dataset.pushData({ searchString, imageUrl });
30    }
31});
Developer
Maintained by Community