From 725e72620e0bdd84b8b8f4d8d469e467ce011555 Mon Sep 17 00:00:00 2001 From: Jasir Zaeem <20666236+JasirZaeem@users.noreply.github.com> Date: Thu, 3 Jul 2025 01:38:54 +0530 Subject: [PATCH 1/5] Init ts impl --- .gitignore | 3 +++ bin/extractor.ts | 1 + mise.toml | 11 +++++++++++ package.json | 19 +++++++++++++++++++ 4 files changed, 34 insertions(+) create mode 100644 bin/extractor.ts create mode 100644 mise.toml create mode 100644 package.json diff --git a/.gitignore b/.gitignore index fb7a88e1..f1b827b7 100644 --- a/.gitignore +++ b/.gitignore @@ -49,3 +49,6 @@ build-iPhoneSimulator/ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this: .rvmrc .DS_Store + +# node +node_modules/ diff --git a/bin/extractor.ts b/bin/extractor.ts new file mode 100644 index 00000000..5d223ab0 --- /dev/null +++ b/bin/extractor.ts @@ -0,0 +1 @@ +console.log('init') diff --git a/mise.toml b/mise.toml new file mode 100644 index 00000000..1539c3c1 --- /dev/null +++ b/mise.toml @@ -0,0 +1,11 @@ +[tools] +node = "24" + +[tasks.install] +alias = "i" +description = "Install dependencies" +run = "npm install" + +[tasks.'ts:extract'] +description = "Extract artworks with the TypeScript implementation" +run = "npm -s run extract" diff --git a/package.json b/package.json new file mode 100644 index 00000000..59eb98b2 --- /dev/null +++ b/package.json @@ -0,0 +1,19 @@ +{ + "name": "serpapi-code-challenge", + "version": "1.0.0", + "description": "Extract artworks from google artworks knowledge panel", + "license": "MIT", + "author": "Jasir Zaeem", + "type": "module", + "main": "bin/extractor.ts", + "scripts": { + "extract": "node bin/extractor.ts" + }, + "dependencies": { + "cheerio": "^1.1.0" + }, + "devDependencies": { + "@types/node": "^24.0.10", + "typescript": "^5.8.3" + } +} From 96c8baa918d0ab2b4336b8062f603a628a5569a8 Mon Sep 17 00:00:00 2001 From: Jasir Zaeem <20666236+JasirZaeem@users.noreply.github.com> Date: Thu, 3 Jul 2025 01:46:42 +0530 Subject: [PATCH 2/5] Implement ts solution --- bin/extractor.ts | 25 ++- files/hokusai-artwork.html | 29 +++ files/mc-escher-artwork.html | 30 +++ lib/extractor.ts | 166 +++++++++++++++++ mise.toml | 14 ++ package-lock.json | 347 +++++++++++++++++++++++++++++++++++ package.json | 3 +- spec/extractor.spec.ts | 93 ++++++++++ tsconfig.json | 113 ++++++++++++ 9 files changed, 818 insertions(+), 2 deletions(-) create mode 100644 files/hokusai-artwork.html create mode 100644 files/mc-escher-artwork.html create mode 100644 lib/extractor.ts create mode 100644 package-lock.json create mode 100644 spec/extractor.spec.ts create mode 100644 tsconfig.json diff --git a/bin/extractor.ts b/bin/extractor.ts index 5d223ab0..f8e657a1 100644 --- a/bin/extractor.ts +++ b/bin/extractor.ts @@ -1 +1,24 @@ -console.log('init') +import {extractArtworksFromSERPFile} from "../lib/extractor.ts"; + +async function main() { + const serpPath = process.argv[2]; + if (!serpPath) { + console.error('Please provide the path to the Google search results page HTML file.'); + console.error('\tUsage: npm run extract '); + console.error('\tExample: npm run extract ./files/van-gogh-paintings.html'); + process.exit(1); + } + + try { + const artworks = await extractArtworksFromSERPFile(serpPath); + console.log(JSON.stringify({artworks}, null, 2)); + } catch (error) { + console.error('Error extracting artworks:', error); + process.exit(1); + } +} + +if (import.meta.url === `file://${process.argv[1]}`) { + await main(); +} + diff --git a/files/hokusai-artwork.html b/files/hokusai-artwork.html new file mode 100644 index 00000000..2cb63ede --- /dev/null +++ b/files/hokusai-artwork.html @@ -0,0 +1,29 @@ +hokusai artwork - Google Search

Accessibility links

About 11,400,000 results (1.20 seconds) 
Hokusai
Google apps
diff --git a/files/mc-escher-artwork.html b/files/mc-escher-artwork.html new file mode 100644 index 00000000..7a7c631c --- /dev/null +++ b/files/mc-escher-artwork.html @@ -0,0 +1,30 @@ +mc escher artwork - Google Search

Accessibility links

About 4,670,000 results (0.95 seconds) 
Maurits Cornelis Escher
Google apps
diff --git a/lib/extractor.ts b/lib/extractor.ts new file mode 100644 index 00000000..fa35a578 --- /dev/null +++ b/lib/extractor.ts @@ -0,0 +1,166 @@ +import type {CheerioAPI} from "cheerio"; +import * as cheerio from 'cheerio'; +import {readFile} from "node:fs/promises"; + +export type Artwork = { + name: string; + /** + * Extra information about the year, only the year right now. + */ + extensions?: string[]; + /** + * URL for the search page for this artwork. + */ + link: string; + /** + * Base64 encoded image or URL to the image of the artwork. + */ + image: string; +} + +// Relevant script tags end with this i.e. statement that sets the src of the lazy loaded images. +const SCRIPT_MARKER = "_setImagesSrc(ii,s"; + +const IMAGE_DATA_REGEX = new RegExp(/var s='(.*?)';/); +const IMAGE_ID_REGEX = new RegExp(/var ii=\['(.*?)'];/); + +/** + * Google serp has images that are lazily rendered, their data is stored in + * variables in the script tags in base64 encoding. The tags contain ids for + * their respective images. At runtime these scripts replace the src attribute + * of their images with the base64 encoded data. This function go to all of + * these script tags and collects the image ids and their base64 encoded data. + * Script tags look like this (prettified): + * ```js + * (function() { + * var s = 'image data encoded in base64'; + * var ii = ['image-id']; + * var r = ''; // may be omitted + * _setImageSrc(ii, s, r); // 'r' may be omitted + * })(); + * ``` + * @param $ - Cheerio object containing the parsed HTML of the Google search results page. + * @return A map where keys are image IDs and values are base64 encoded image data. + */ +function collectLazyImages($: CheerioAPI): Map { + const lazyImages = new Map(); + + $('script').each((_, script) => { + const scriptContent = $(script).html(); + if (!scriptContent) return; + + if (!scriptContent.includes(SCRIPT_MARKER)) { + // Ignore irrelevant script tags that do not contain image data + return; + } + + const idMatch = scriptContent.match(IMAGE_ID_REGEX); + if (!idMatch || !idMatch[1] || idMatch[1].length === 0) { + return; + } + const imageId = idMatch[1]; + + // Extract the base64 encoded image data from the script content + const dataMatch = scriptContent.match(IMAGE_DATA_REGEX); + if (!dataMatch || !dataMatch[1] || dataMatch[1].length === 0) { + console.warn(`No image data found for image ID: ${imageId}`); + return; + } + // Un-escape the padding '=' characters in the base64 string from '\\x3d' to '=' + const unescapedImageData = dataMatch[1].replaceAll('\\x3d', '='); + lazyImages.set(imageId, unescapedImageData); + }) + + return lazyImages; +} + +// CSS selectors for extracting artworks from the Google knowledge panel. + +const ARTWORK_CONTAINER_ANCHOR_SELECTOR = 'div.iELo6 > a'; +const ARTWORK_NAME_SELECTOR = 'div.pgNMRc'; +const ARTWORK_YEAR_SELECTOR = 'div.cxzHyb'; +const ARTWORK_IMAGE_SELECTOR = 'img.taFZJe'; + +const GOOGLE_BASE_URL = 'https://www.google.com'; + + +/** + * Extracts artworks from the artwork knowledge panel in a Google search results page. + * Structure: + * ```html + * + * ``` + * @param pageHtml - The HTML content of the Google search results page containing the knowledge panel. + * @return A promise that resolves to an array of artworks extracted from the knowledge panel. + * @throws Error if the HTML cannot be parsed or if the expected structure is not found. + */ +export async function extractArtworksFromKnowledgePanel(pageHtml: string): Promise { + const $ = cheerio.load(pageHtml); + const lazyImages = collectLazyImages($); + const artworks: Artwork[] = []; + + $(ARTWORK_CONTAINER_ANCHOR_SELECTOR).each( + (_, element) => { + const $element = $(element); + + const name = $element.find(ARTWORK_NAME_SELECTOR).text().trim(); + const year = $element.find(ARTWORK_YEAR_SELECTOR).text().trim(); + const href = $element.attr('href'); + + const imageElement = $element.find(ARTWORK_IMAGE_SELECTOR); + // Visible artworks only have a src attribute with the base64 encoded + // image. Hidden artworks in the truncated part of the knowledge panel + // have a data-src attribute with a remote URL that is fetched and + // displayed as base64 when the user expands the knowledge panel. We get + // the remote url from data-src if it exists, otherwise we use the base64 + // encoded image from the src attribute. + const image = lazyImages.get(imageElement.attr('id') || '') || imageElement.attr('data-src'); + + if (!name || !href || !image) { + console.warn(`Artwork element is missing required fields: name='${name}', href='${href}', image='${image}'`); + return; + } + + // Normalize relative image search URLs to absolute URLs + const link = new URL(href, GOOGLE_BASE_URL).href; + + const extensions = year ? [year] : undefined; + + artworks.push({ + name, + extensions, + link, + image + }); + } + ) + + return artworks; +} + + +/** + * @param serpPath - The path to the Google search results page html file. + * @return A promise that resolves to an array of artworks extracted from the knowledge panel. + * @throws Error if the file cannot be read or parsed. + */ +export async function extractArtworksFromSERPFile(serpPath: string): Promise { + const html = await readFile(serpPath, 'utf-8'); + return extractArtworksFromKnowledgePanel(html); +} diff --git a/mise.toml b/mise.toml index 1539c3c1..d43385df 100644 --- a/mise.toml +++ b/mise.toml @@ -1,4 +1,5 @@ [tools] +jq = "1" node = "24" [tasks.install] @@ -9,3 +10,16 @@ run = "npm install" [tasks.'ts:extract'] description = "Extract artworks with the TypeScript implementation" run = "npm -s run extract" + +[tasks.test] +description = "Run tests" +run = [ + "npm run test", + "echo 'Comparing solution with expected output...'", + """ + diff \\ + <(mise run ts:extract './files/van-gogh-paintings.html' | jq --sort-keys) \\ + <(cat ./files/expected-array.json | jq --sort-keys) + """, + "echo 'Tests completed successfully'" +] diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..46a76d47 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,347 @@ +{ + "name": "code-challenge", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "code-challenge", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "cheerio": "^1.1.0" + }, + "devDependencies": { + "@types/node": "^24.0.10", + "typescript": "^5.8.3" + } + }, + "node_modules/@types/node": { + "version": "24.0.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.10.tgz", + "integrity": "sha512-ENHwaH+JIRTDIEEbDK6QSQntAYGtbvdDXnMXnZaZ6k13Du1dPMmprkEHIL7ok2Wl2aZevetwTAb5S+7yIF+enA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.8.0" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" + }, + "node_modules/cheerio": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.1.0.tgz", + "integrity": "sha512-+0hMx9eYhJvWbgpKV9hN7jg0JcwydpopZE4hgi+KvQtByZXPp04NiCWU0LzcAbP63abZckIHkTQaXVF52mX3xQ==", + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "encoding-sniffer": "^0.2.0", + "htmlparser2": "^10.0.0", + "parse5": "^7.3.0", + "parse5-htmlparser2-tree-adapter": "^7.1.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^7.10.0", + "whatwg-mimetype": "^4.0.0" + }, + "engines": { + "node": ">=18.17" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/encoding-sniffer": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz", + "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==", + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" + }, + "funding": { + "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/htmlparser2": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.0.0.tgz", + "integrity": "sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.1", + "entities": "^6.0.0" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", + "license": "MIT", + "dependencies": { + "domhandler": "^5.0.3", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "license": "MIT", + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.11.0.tgz", + "integrity": "sha512-heTSIac3iLhsmZhUCjyS3JQEkZELateufzZuBaVM5RHXdSBMb1LPMQf5x+FH7qjsZYDP0ttAc3nnVpUB+wYbOg==", + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/undici-types": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", + "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==", + "dev": true, + "license": "MIT" + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "license": "MIT", + "engines": { + "node": ">=18" + } + } + } +} diff --git a/package.json b/package.json index 59eb98b2..89aede11 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "type": "module", "main": "bin/extractor.ts", "scripts": { - "extract": "node bin/extractor.ts" + "extract": "node bin/extractor.ts", + "test": "node --test spec/*.spec.ts" }, "dependencies": { "cheerio": "^1.1.0" diff --git a/spec/extractor.spec.ts b/spec/extractor.spec.ts new file mode 100644 index 00000000..782bec11 --- /dev/null +++ b/spec/extractor.spec.ts @@ -0,0 +1,93 @@ +import test from 'node:test'; +import assert from 'node:assert'; +import {readFile} from 'node:fs/promises'; +import {type Artwork, extractArtworksFromKnowledgePanel, extractArtworksFromSERPFile} from '../lib/extractor.ts'; + +const TEST_PAGES = [ + './files/van-gogh-paintings.html', + './files/mc-escher-artwork.html', + './files/hokusai-artwork.html', +] + +/** + * Placeholder used by google for images that are not loaded yet (because they + * are in the truncated part of the knowledge panel). They shouldn't show up in + * the extracted artworks because their alternative remote url should be + * extracted instead. + */ +const PLACEHOLDER_BASE64_IMAGE = 'data:image/gif;base64,R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==' + +/** + * Validates that the given artwork object conforms to the expected structure. + * @param artwork - The artwork object to validate. + * @param artworkId - Identifier for the artwork, used in error messages. + * @throws AssertionError Will throw an error if the artwork does not conform to the expected structure. + */ +function validateArtwork(artwork: unknown, artworkId: string): asserts artwork is Artwork { + assert(typeof artwork === 'object' && artwork !== null, `Artwork #${artworkId} should be an object, got ${typeof artwork}`); + + assert('name' in artwork, `Artwork #${artworkId} should have a name`); + assert(typeof artwork.name === 'string', `Artwork #${artworkId} name should be a string, got ${typeof artwork.name}`); + assert(artwork.name.length > 0, `Artwork #${artworkId} name should not be empty`); + + if ('extensions' in artwork && artwork.extensions !== undefined) { + assert(Array.isArray(artwork.extensions), `Artwork #${artworkId} extensions should be an array`); + if (artwork.extensions.length > 0) { + artwork.extensions.forEach(extension => { + assert(typeof extension === 'string', `Artwork #${artworkId} each extension should be a string`); + assert(extension.length > 0, `Artwork #${artworkId} Extension should not be empty`); + }); + } + } + + assert('link' in artwork, `Artwork #${artworkId} Artwork should have a link`); + assert(typeof artwork.link === 'string', `Artwork #${artworkId} Artwork link should be a string, got ${typeof artwork.link}`); + assert(artwork.link.length > 0, `Artwork #${artworkId} link should not be empty`); + assert.match(artwork.link, /^https:\/\/www\.google\.com\//, `Artwork #${artworkId} link should be an absolute Google URL`); + + assert('image' in artwork, `Artwork #${artworkId} should have an image`); + assert(typeof artwork.image === 'string', `Artwork #${artworkId} image should be a string, got ${typeof artwork.image}`); + assert(artwork.image.length > 0, `Artwork #${artworkId} image should not be empty`); + + assert.match(artwork.image, /^(data:image\/(png|jpeg|gif);base64,|https)/, `Artwork #${artworkId} image should be a base64 encoded image or a URL`); + assert.notEqual(artwork.image, PLACEHOLDER_BASE64_IMAGE, `Artwork #${artworkId} image should not be the placeholder base64 image`); +} + +test('extractArtworksFromSERPFile should extract artworks from van Gogh HTML file', async () => { + + for (const page of TEST_PAGES) { + const artworks = await extractArtworksFromSERPFile(page); + assert(Array.isArray(artworks), `Should return an array for ${page}`); + assert(artworks.length > 0, `Should extract at least one artwork from ${page}`); + + artworks.forEach((artwork, index) => { + validateArtwork(artwork, `${page} #${index + 1}`); + }); + } +}); + +test('extractArtworksFromKnowledgePanel should extract artworks from HTML string', async () => { + const page = TEST_PAGES[0] + const html = await readFile(page, 'utf-8'); + const artworks = await extractArtworksFromKnowledgePanel(html); + assert(Array.isArray(artworks), 'Should return an array'); + assert(artworks.length > 0, 'Should extract at least one artwork'); + + artworks.forEach((artwork, index) => { + validateArtwork(artwork, `${page} #${index + 1}`); + }); +}); + +test('extractArtworksFromKnowledgePanel should handle empty HTML', async () => { + const artworks = await extractArtworksFromKnowledgePanel(''); + + assert(Array.isArray(artworks), 'Should return an array'); + assert.strictEqual(artworks.length, 0, 'Should return empty array for HTML without artwork containers'); +}); + +test('extractArtworksFromSERPFile should reject for non-existent file', async () => { + await assert.rejects( + extractArtworksFromSERPFile('./non-existent-file.html'), + 'Should reject when file does not exist' + ); +}); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..b4eaaffe --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,113 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "ESNext", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "libReplacement": true, /* Enable lib replacement. */ + // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "NodeNext", /* Specify what module code is generated. */ + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "rewriteRelativeImportExtensions": true, /* Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files. */ + // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ + // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ + // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "noUncheckedSideEffectImports": true, /* Check side effect imports. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + // "outDir": "./", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ + // "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */ + // "erasableSyntaxOnly": true, /* Do not allow runtime constructs that are not part of ECMAScript. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "strictBuiltinIteratorReturn": true, /* Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +} From 2c96bf94639015dd1eb7bb29be1a08bec739d477 Mon Sep 17 00:00:00 2001 From: Jasir Zaeem <20666236+JasirZaeem@users.noreply.github.com> Date: Thu, 3 Jul 2025 01:56:59 +0530 Subject: [PATCH 3/5] Init ruby impl --- .rspec | 3 +++ Gemfile | 4 ++++ Gemfile.lock | 51 ++++++++++++++++++++++++++++++++++++++++++ bin/extractor.rb | 1 + lib/extractor.rb | 6 +++++ mise.toml | 11 ++++++++- spec/extractor_spec.rb | 3 +++ spec/spec_helper.rb | 15 +++++++++++++ 8 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 .rspec create mode 100644 Gemfile create mode 100644 Gemfile.lock create mode 100644 bin/extractor.rb create mode 100644 lib/extractor.rb create mode 100644 spec/extractor_spec.rb create mode 100644 spec/spec_helper.rb diff --git a/.rspec b/.rspec new file mode 100644 index 00000000..34c5164d --- /dev/null +++ b/.rspec @@ -0,0 +1,3 @@ +--format documentation +--color +--require spec_helper diff --git a/Gemfile b/Gemfile new file mode 100644 index 00000000..1c600fe8 --- /dev/null +++ b/Gemfile @@ -0,0 +1,4 @@ +source 'https://rubygems.org' + +gem 'nokogiri' +gem 'rspec' \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 00000000..c0c1fd62 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,51 @@ +GEM + remote: https://rubygems.org/ + specs: + diff-lcs (1.6.2) + nokogiri (1.18.8-aarch64-linux-gnu) + racc (~> 1.4) + nokogiri (1.18.8-aarch64-linux-musl) + racc (~> 1.4) + nokogiri (1.18.8-arm-linux-gnu) + racc (~> 1.4) + nokogiri (1.18.8-arm-linux-musl) + racc (~> 1.4) + nokogiri (1.18.8-arm64-darwin) + racc (~> 1.4) + nokogiri (1.18.8-x86_64-darwin) + racc (~> 1.4) + nokogiri (1.18.8-x86_64-linux-gnu) + racc (~> 1.4) + nokogiri (1.18.8-x86_64-linux-musl) + racc (~> 1.4) + racc (1.8.1) + rspec (3.13.1) + rspec-core (~> 3.13.0) + rspec-expectations (~> 3.13.0) + rspec-mocks (~> 3.13.0) + rspec-core (3.13.5) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.5) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.5) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-support (3.13.4) + +PLATFORMS + aarch64-linux-gnu + aarch64-linux-musl + arm-linux-gnu + arm-linux-musl + arm64-darwin + x86_64-darwin + x86_64-linux-gnu + x86_64-linux-musl + +DEPENDENCIES + nokogiri + rspec + +BUNDLED WITH + 2.6.7 diff --git a/bin/extractor.rb b/bin/extractor.rb new file mode 100644 index 00000000..3e9605f8 --- /dev/null +++ b/bin/extractor.rb @@ -0,0 +1 @@ +puts 'init' \ No newline at end of file diff --git a/lib/extractor.rb b/lib/extractor.rb new file mode 100644 index 00000000..f7e4ddd2 --- /dev/null +++ b/lib/extractor.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +module Extractor + class Error < StandardError; end + +end \ No newline at end of file diff --git a/mise.toml b/mise.toml index d43385df..0ea3ca3d 100644 --- a/mise.toml +++ b/mise.toml @@ -1,20 +1,29 @@ [tools] jq = "1" node = "24" +ruby = "3" [tasks.install] alias = "i" description = "Install dependencies" -run = "npm install" +run = [ + "npm install", + "bundle install" +] [tasks.'ts:extract'] description = "Extract artworks with the TypeScript implementation" run = "npm -s run extract" +[tasks.'ruby:extract'] +description = "Extract artworks with the Ruby implementation" +run = "ruby ./bin/extractor.rb" + [tasks.test] description = "Run tests" run = [ "npm run test", + "bundle exec rspec", "echo 'Comparing solution with expected output...'", """ diff \\ diff --git a/spec/extractor_spec.rb b/spec/extractor_spec.rb new file mode 100644 index 00000000..060abbb8 --- /dev/null +++ b/spec/extractor_spec.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +puts 'test extractor' \ No newline at end of file diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 00000000..7e3d64c8 --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +require "./lib/extractor" + +RSpec.configure do |config| + # Enable flags like --only-failures and --next-failure + config.example_status_persistence_file_path = ".rspec_status" + + # Disable RSpec exposing methods globally on `Module` and `main` + config.disable_monkey_patching! + + config.expect_with :rspec do |c| + c.syntax = :expect + end +end From 024a8130813fd3d023d8697b0866a8d19e15dfc8 Mon Sep 17 00:00:00 2001 From: Jasir Zaeem <20666236+JasirZaeem@users.noreply.github.com> Date: Thu, 3 Jul 2025 02:03:27 +0530 Subject: [PATCH 4/5] Implement ruby version --- bin/extractor.rb | 27 +++++++- lib/extractor.rb | 151 ++++++++++++++++++++++++++++++++++++++++- mise.toml | 7 +- spec/extractor_spec.rb | 108 ++++++++++++++++++++++++++++- 4 files changed, 288 insertions(+), 5 deletions(-) diff --git a/bin/extractor.rb b/bin/extractor.rb index 3e9605f8..4d7ecf6b 100644 --- a/bin/extractor.rb +++ b/bin/extractor.rb @@ -1 +1,26 @@ -puts 'init' \ No newline at end of file +require './lib/extractor' +require 'json' + +def main + if ARGV.empty? + puts('Please provide the path to the Google search results page HTML file.') + puts("\tUsage: ruby #{$PROGRAM_NAME} ") + puts("\tExample: ruby #{$PROGRAM_NAME} ./files/van-gogh-paintings.html") + exit(1) + end + + serp_path = ARGV[0] + + begin + artworks = Extractor.extract_artworks_from_serp_file(serp_path) + puts(JSON.pretty_generate({ artworks: artworks })) + rescue StandardError => e + puts("An error occurred while extracting artworks: #{e.message}") + exit(1) + end + +end + +if __FILE__ == $PROGRAM_NAME + main +end \ No newline at end of file diff --git a/lib/extractor.rb b/lib/extractor.rb index f7e4ddd2..d1259d5d 100644 --- a/lib/extractor.rb +++ b/lib/extractor.rb @@ -1,6 +1,155 @@ # frozen_string_literal: true +require 'nokogiri' +require 'uri' module Extractor class Error < StandardError; end -end \ No newline at end of file + # Relevant script tags end with this i.e. statement that sets the src of the lazy loaded images. + SCRIPT_MARKER = '_setImagesSrc(ii,s' + IMAGE_DATA_REGEX = Regexp.new(/var s='(.*?)';/) + IMAGE_ID_REGEX = Regexp.new(/var ii=\['(.*?)'\];/) + + # Google serp has images that are lazily rendered, their data is stored in + # variables in the script tags in base64 encoding. The tags contain ids for + # their respective images. At runtime these scripts replace the src attribute + # of their images with the base64 encoded data. This function go to all of + # these script tags and collects the image ids and their base64 encoded data. + # Script tags look like this (prettified): + # ```js + # (function() { + # var s = 'image data encoded in base64'; + # var ii = ['image-id']; + # var r = ''; // may be omitted + # _setImageSrc(ii, s, r); // 'r' may be omitted + # })(); + # ``` + # @param doc [Nokogiri::HTML::Document] The parsed HTML document containing the script tags. + # @return [Hash] A hash where keys are image IDs and values are the base64 encoded image data. + def self.collect_lazy_images(doc) + images = {} + + doc.search('script').each do |script| + next unless script.text.include?(SCRIPT_MARKER) + + id_match = script.text.match(IMAGE_ID_REGEX) + if id_match.nil? || id_match[1].nil? || id_match[1].empty? + warn("Script tag is missing image ID: #{script.text.inspect}") + next + end + image_id = id_match[1] + + data_match = script.text.match(IMAGE_DATA_REGEX) + if data_match.nil? || data_match[1].nil? || data_match[1].empty? + warn("Script tag is missing base64 data: #{script.text.inspect}") + next + end + # Un-escape the padding '=' characters in the base64 string from '\\x3d' to '=' + image_data = data_match[1].gsub("\\x3d", '=') + + # Store the base64 data with the corresponding image ID + images[image_id] = image_data + end + + images + end + + # CSS selectors for extracting artworks from the Google knowledge panel. + + ARTWORK_CONTAINER_ANCHOR_SELECTOR = 'div.iELo6 > a' + ARTWORK_NAME_SELECTOR = 'div.pgNMRc' + ARTWORK_YEAR_SELECTOR = 'div.cxzHyb' + ARTWORK_IMAGE_SELECTOR = 'img.taFZJe' + + GOOGLE_BASE_URL = 'https://www.google.com' + + # Extracts artworks from the artwork knowledge panel in a Google search results page. + # Structure: + # + # @param html [String] The HTML content of the Google search results page. + # @return [Array] An array of hashes, each containing details of an artwork. + def self.extract_artworks_from_knowledge_panel(html) + doc = Nokogiri::HTML(html) + lazy_images = collect_lazy_images(doc) + artworks = [] + + doc.search(ARTWORK_CONTAINER_ANCHOR_SELECTOR).each do |element| + name = element.at_css(ARTWORK_NAME_SELECTOR).text.strip + year = element.at_css(ARTWORK_YEAR_SELECTOR).text.strip + + href = element['href'] + unless href.is_a?(String) + warn("Artwork element is missing href: name=#{name.inspect}") + next + end + + image_element = element.at_css(ARTWORK_IMAGE_SELECTOR) + # Visible artworks only have a src attribute with the base64 encoded + # image. Hidden artworks in the truncated part of the knowledge panel + # have a data-src attribute with a remote URL that is fetched and + # displayed as base64 when the user expands the knowledge panel. We get + # the remote url from data-src if it exists, otherwise we use the base64 + # encoded image from the src attribute. + image = lazy_images[image_element['id']] || image_element['data-src'] + unless image.is_a?(String) + warn("Artwork element is missing image: name=#{name.inspect}") + next + end + + if name.empty? || href.empty? || image.empty? + warn("Artwork element is missing required fields: name=#{name.inspect}, href=#{href.inspect}, image=#{image.inspect}") + next + end + + link = URI.join(GOOGLE_BASE_URL, href).to_s + + artwork = { + name: name, + link: link, + image: image, + } + + unless year.empty? + artwork[:extensions] = [year] + end + + artworks.append(artwork) + end + + artworks + end + + # @param serp_path [String] The path to the Google search results page HTML file. + # @return [Array] An array of hashes, each containing details of an artwork. + def self.extract_artworks_from_serp_file(serp_path) + if serp_path.nil? || serp_path.empty? + raise ArgumentError, 'Please provide the path to the Google search results page HTML file.' + end + + begin + html_content = File.read(serp_path) + self.extract_artworks_from_knowledge_panel(html_content) + rescue Errno::ENOENT + raise Error, "File not found: #{serp_path}" + rescue StandardError => e + raise Error, "An error occurred while reading the file: #{e.message}" + end + end + +end diff --git a/mise.toml b/mise.toml index 0ea3ca3d..b15fcca0 100644 --- a/mise.toml +++ b/mise.toml @@ -24,11 +24,14 @@ description = "Run tests" run = [ "npm run test", "bundle exec rspec", - "echo 'Comparing solution with expected output...'", + "echo 'Comparing solutions with expected output...'", """ diff \\ <(mise run ts:extract './files/van-gogh-paintings.html' | jq --sort-keys) \\ - <(cat ./files/expected-array.json | jq --sort-keys) + <(cat ./files/expected-array.json | jq --sort-keys) \\ + && diff \\ + <(mise run ruby:extract './files/van-gogh-paintings.html' | jq --sort-keys) \\ + <(cat ./files/expected-array.json | jq --sort-keys) """, "echo 'Tests completed successfully'" ] diff --git a/spec/extractor_spec.rb b/spec/extractor_spec.rb index 060abbb8..2c872396 100644 --- a/spec/extractor_spec.rb +++ b/spec/extractor_spec.rb @@ -1,3 +1,109 @@ # frozen_string_literal: true -puts 'test extractor' \ No newline at end of file +RSpec.describe Extractor do + let(:test_pages) do + %w[./files/van-gogh-paintings.html ./files/mc-escher-artwork.html ./files/hokusai-artwork.html] + end + + # Placeholder used by google for images that are not loaded yet (because they + # are in the truncated part of the knowledge panel). They shouldn't show up in + # the extracted artworks because their alternative remote url should be + # extracted instead. + let(:placeholder_base64_image) do + 'data:image/gif;base64,R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==' + end + + # Validates that the given artwork hash conforms to the expected structure. + def validate_artwork(artwork, artwork_id) + expect(artwork).to be_a(Hash), "Artwork ##{artwork_id} should be a hash, got #{artwork.class}" + + expect(artwork).to have_key(:name), "Artwork ##{artwork_id} should have a name" + expect(artwork[:name]).to be_a(String), "Artwork ##{artwork_id} name should be a string, got #{artwork[:name].class}" + expect(artwork[:name]).not_to be_empty, "Artwork ##{artwork_id} name should not be empty" + + if artwork.key?(:extensions) && !artwork[:extensions].nil? + expect(artwork[:extensions]).to be_a(Array), "Artwork ##{artwork_id} extensions should be an array" + if artwork[:extensions].any? + artwork[:extensions].each do |extension| + expect(extension).to be_a(String), "Artwork ##{artwork_id} each extension should be a string" + expect(extension).not_to be_empty, "Artwork ##{artwork_id} extension should not be empty" + end + end + end + + expect(artwork).to have_key(:link), "Artwork ##{artwork_id} should have a link" + expect(artwork[:link]).to be_a(String), "Artwork ##{artwork_id} link should be a string, got #{artwork[:link].class}" + expect(artwork[:link]).not_to be_empty, "Artwork ##{artwork_id} link should not be empty" + expect(artwork[:link]).to match(/\Ahttps:\/\/www\.google\.com\//), "Artwork ##{artwork_id} link should be an absolute Google URL" + + expect(artwork).to have_key(:image), "Artwork ##{artwork_id} should have an image" + expect(artwork[:image]).to be_a(String), "Artwork ##{artwork_id} image should be a string, got #{artwork[:image].class}" + expect(artwork[:image]).not_to be_empty, "Artwork ##{artwork_id} image should not be empty" + + expect(artwork[:image]).to match(/\A(data:image\/(png|jpeg|gif);base64,|https)/), "Artwork ##{artwork_id} image should be a base64 encoded image or a URL" + + expect(artwork[:image]).not_to eq(placeholder_base64_image), "Artwork ##{artwork_id} image should not be the placeholder base64 image" + end + + describe '.extract_artworks_from_serp_file' do + it 'extracts artworks from all test HTML files' do + test_pages.each do |page| + artworks = described_class.extract_artworks_from_serp_file(page) + + expect(artworks).to be_a(Array), "Should return an array for #{page}" + expect(artworks.length).to be > 0, "Should extract at least one artwork from #{page}" + + artworks.each_with_index do |artwork, index| + validate_artwork(artwork, "#{page} ##{index + 1}") + end + end + end + + it 'raises an error for non-existent file' do + expect { + described_class.extract_artworks_from_serp_file('./non-existent-file.html') + }.to raise_error(Extractor::Error, /File not found/) + end + + it 'raises an error for nil path' do + expect { + described_class.extract_artworks_from_serp_file(nil) + }.to raise_error(ArgumentError, /Please provide the path/) + end + + it 'raises an error for empty path' do + expect { + described_class.extract_artworks_from_serp_file('') + }.to raise_error(ArgumentError, /Please provide the path/) + end + end + + describe '.extract_artworks_from_knowledge_panel' do + it 'extracts artworks from HTML string' do + page = test_pages.first + html_content = File.read(page) + artworks = described_class.extract_artworks_from_knowledge_panel(html_content) + + expect(artworks).to be_a(Array), 'Should return an array' + expect(artworks.length).to be > 0, 'Should extract at least one artwork' + + artworks.each_with_index do |artwork, index| + validate_artwork(artwork, "#{page} ##{index + 1}") + end + end + + it 'handles empty HTML' do + artworks = described_class.extract_artworks_from_knowledge_panel('') + + expect(artworks).to be_a(Array), 'Should return an array' + expect(artworks.length).to eq(0), 'Should return empty array for HTML without artwork containers' + end + + it 'handles malformed HTML' do + artworks = described_class.extract_artworks_from_knowledge_panel('
invalid
') + + expect(artworks).to be_a(Array), 'Should return an array' + expect(artworks.length).to eq(0), 'Should return empty array for malformed HTML' + end + end +end From dac4bc664826542e5cd2593e6b89984ade7d6386 Mon Sep 17 00:00:00 2001 From: Jasir Zaeem <20666236+JasirZaeem@users.noreply.github.com> Date: Thu, 3 Jul 2025 02:06:05 +0530 Subject: [PATCH 5/5] Add docs --- README.md | 166 ++++++++++++++++++++++++++++++++++++ files/artwork-structure.png | Bin 0 -> 115229 bytes 2 files changed, 166 insertions(+) create mode 100644 files/artwork-structure.png diff --git a/README.md b/README.md index 4d5a093f..1d2beda6 100644 --- a/README.md +++ b/README.md @@ -26,3 +26,169 @@ Add also to your array the painting thumbnails present in the result page file ( Test against 2 other similar result pages to make sure it works against different layouts. (Pages that contain the same kind of carrousel. Don't necessarily have to be paintings.) The suggested time for this challenge is 4 hours. But, you can take your time and work more on it if you want. + +------------------------------------------------------------------------------- + +# Solution + +The source of the page contains images in the markup of the artwork knowledge panel in two forms. Images above the fold +that are not in the truncated part of the panel, are embedded as base64 encoded data in the page itself. Image not +visible contains links to the image files to display, which are fetched when user expands the section. + +Each artwork in the panel has the following structure: +![Artwork Structure](./files/artwork-structure.png) + +```html + + + +## Implementation +``` + +### Extracting Images + +Extracting the other values is straightforward, but images require special handling due to their different formats: + +- For the remote images, the solution extracts the image url from the `data-src` attribute +- For the embedded images, the solution extracts the data from script tags. The source contains script tags with the + base64 encoded image data for lazily rendered images. These script tags can be associated with their respective + artwork using the id attribute on image and `ii` variable in the script. Then the image data can be extracted from the + `s` variable in the script tag. + +## Code + +Since I did not have prior ruby experience I implemented a solution in TypeScript using the `cheerio` library for HTML +parsing. + +Following that I caught up on some ruby basics, and then implemented a ruby solution with the typescript code as the +reference implementation. + +### Files + +```txt +├── bin +│ ├── extractor.rb - Ruby script to run the extractor +│ └── extractor.ts - TypeScript script to run the extractor +├── files - Test HTML files +│ ├── ... +│ ├── hokusai-artwork.html +│ ├── mc-escher-artwork.html +│ ├── van-gogh-paintings.html +│ └── ... +├── ... +├── lib +│ ├── extractor.rb - Ruby extractor functionality +│ └── extractor.ts - TypeScript extractor functionality +├── ... +├── spec +│ ├── extractor_spec.rb - Ruby RSpec tests for the extractor +│ ├── extractor.spec.ts - TypeScript tests using the node builtin test utils +│ └── spec_helper.rb +└── ... +``` + +## Running the code + +### Setup + +#### With Mise + +If you have [Mise](https://github.com/jdx/mise) you can use that to set up the environment for both node and ruby. + +```bash +mise install +``` + +#### Without Mise - Node + +You'd need node > `23.6` (or node > `22.6` and with `--experimental-strip-types`) to run the typescript code. After +ensuring you have that, install dependencies: + +```bash +npm install +``` + +#### Without Mise - Ruby + +You'd need ruby > `3.0` to run the ruby code. After ensuring you have that, install dependencies: + +```bash +bundle install +``` + +### Running + +#### With Mise + +Test the code with: + +```bash +mise run test +``` + +This will run tests for the typescript version and the ruby version. Then run both and compare each of their outputs +with the output in `expected-array.json` file. + +Run ts version with: + +```bash +mise run ts:extract # Optionally pipe through jq for syntax highlighting `| jq` +``` + +Run ruby version with: + +```bash +mise run ruby:extract # Optionally pipe through jq for syntax highlighting `| jq` +``` + +#### Without Mise + +Run tests + +```bash +npm test # For typescript +bundle exec rspec # For ruby +``` + +Run extractor +For typescript + +```bash +npm run extract +``` + +For ruby + +```bash +ruby bin/extractor.rb +``` + +#### Examples + +```bash +mise run ts:extract files/van-gogh-paintings.html | jq +mise run ts:extract files/hokusai-artwork.html + +npm run extract files/van-gogh-paintings.html + +ruby bin/extractor.rb files/van-gogh-paintings.html | jq +ruby bin/extractor.rb files/hokusai-artwork.html + +ruby bin/extractor.rb files/mc-escher-artwork.html | jq +``` diff --git a/files/artwork-structure.png b/files/artwork-structure.png new file mode 100644 index 0000000000000000000000000000000000000000..de276f8155406ddf601ab970de8c6861f1f8b2e3 GIT binary patch literal 115229 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

BQ;dubHn= ze7x&)>p_<=bnt3xYwNT)&mMQhR@zLEJH@%^Q%w)QmnDm3Wo4D;&!4wbQdF!Z)q&8t z@q4s&Lk(0y1U=y@wI)WmDMc}Q?y zRL4@I;fjUpU7Eb>r9vNqJ>)dCY0Q|ttvWe$hJ)CHMF+fs&g+op?J=NMis8ZT%2T)J9fkTQfAcd8~WHLWoiEQ9`yu0Pm}uem1=W#~X_C^LaV* zfzH|n37qo}3@kL1M@;71bqc&*Sxk0l>$Ht{C@U-1EXZqHcc?EvCvQ_f91c#r6lc#X z7aMq56;14^+<`uiip>FqVsk zn_iV8V^FNw(7PxmQSG_lO3D(=)?IDf3KTDgRHQ+QFG8C2%k}c_TZ_QQj^ASj2%ZLi z@@X0Of?yY^?mV5^pfa9j+B!1v^*tR~kk;Ami-jxDFky_%-=36WF>O4H{WGmM>LZ;p z)JgVyi>lO5x*;b}2%z2lY zzj(#MT}gCl=XD!|Dmmha6+=IcGM@Rm+Wqg_fgeYdshIX^#tn zsoUL5#-FR>Jq!%eqr}uO6OZHe`SSBi(x34qw`DjVQBqRo`kYWjFG|Gh?|Ue$Y-}j^ zskL+ry_PM@7am_UQq`HMjNmw0N>%e<*6WXoo;dY+({lR3jpDtxWSw&YJrd zv_0l3YYOf48=}2ZhvG~wojHRiEGs3Uw#D3|+IQM;$i9$2y*V9y%5N#idYFhnB|J?_ zPNw=GbxJ7kfzLLKhWI-Taj9;EYNfs5b}bDR)id_q#@$^PJaS8wj@sJVK(N8_5$_u} zH|_D_=IPQ_#zcT(b-r^7;d^`k- zuD{zF{@bGW*%ER=tt#nJ!hil-`f39_p9!533IF}%I0<-iZI~(IkKtV+gd_*JNC}k1 p{CN_?2%enu2-x~#>FN9$eANs2V2_n