Product Comparison App (JS Demo Project)

Mikhail ZubMikhail Zub
6 min read

Intro

The main idea for creating this eBay and Walmart dropshipping product research demo app was to show a practical example of one of the many options for using SerpApi.

This application could be improved to be an actual dropshipping tool (similar to ZikAnalytics for example) to research products to sell, and ability to compare the prices of certain products on eBay and Walmart to calculate profit and other possible criteria.

The backend is written in Node.js, the frontend in React. To create this app I was use the next npm packages:

How to run locally?

📌Note: If you don't want to run the app locally, you can skip this part.

You can download the application files to your computer and run locally:

Run backend

To run the backend you need to create .env file in the backend directory and write your API_KEY in it:

API_KEY="paste here your api key from https://serpapi.com/manage-api-key"

Then run the terminal and enter (you need to be installed Node.js):

*If you don't have Node.js installed, you can download it from nodejs.org and follow the installation documentation.

npm i

And then:

npm start

Now your server is working. To check it go to http://localhost:4004 in your browser. If you see "Cannot GET /" everything is OK.

Run frontend

Let's start our frontend. First, you need to change the backend URL. To do this open src/requests.js and change baseURL to http://localhost:4004. Now your app will send requests to your local backend.

Next, run the terminal in the frontend directory and enter:

npm i

And then:

npm start

After the application starts you can go to http://localhost:3000 in your browser and you may see first screen:

image

How to use?

First, you need to enter a search query with a product name, choose where you want to sell a product and name match accuracy (default is more or equal to 50%) and click the "search" button.

📌Note: because when searching, the Levenshtein distance is used to compare the names of products, the search query must be similar to the full name of the product, otherwise the search will not return matches.

image

Then you need to choose the product you are interested in and click the "compare results" button:

image

And choose a product with a suitable profit and save it in "xlsx" format if you want:

image

How it works?

Because the frontend job is just to show you the information, the main part of the work makes on the backend. So I will try to explain to you how it works.

I'll skip the part where we create the server with express and focus on the part where we parse and process the results. If you don't know how to do it, here's a Hello world express.js example from official docs.

First, when the server receives a request on route "/store", it handles it with getResultsToChoose function:

//index.js
app.post("/store", getResultsToChoose);

In this function we get scraped results depending on targetStore, filter it and send it back to the frontend in the response:

//storeResultsHandler.js
export const getResultsToChoose = async (req, res) => {
  const { targetStore, query, accuracy } = req.body;
  let results;
  if (targetStore === "ebay") {
    const ebayResults = await getStoreResults(targetStore, query);
    results = ebayFiltering(query, accuracy, ebayResults);
  } else {
    const walmartResults = await getStoreResults(targetStore, query);
    results = walmartFiltering(query, accuracy, walmartResults);
  }
  res.status(200).json({ filteredResults: results });
};

getStoreResults is used to get the organic results from the store using Walmart Search Engine Results API and Ebay Search Engine Results API from SerpApi:

//serpApiHandler.js
import dotenv from "dotenv";
import { config, getJson } from "serpapi";

dotenv.config();
config.api_key = process.env.API_KEY; // your SerpApi private key from .env file

// make params to make a request to SerpApi depending on target store
const getParams = (store, query) => {
  switch (store) {
    case "ebay":
      return {
        _nkw: query,
      };
    case "walmart":
      return {
        query,
      };
    default:
      break;
  }
};

// get JSON with results and return organic_results array
const getStoreResults = async (store, query) => {
  const params = getParams(store, query);
  const results = await getJson(store, params);
  return results.organic_results;
};

export default getStoreResults;

After we get organic results (for example from eBay) we filter it, leaving only products which have a buy now price, are in new condition, and match our search query with Levenshtain distance method. And finally sort them in ascending order of price:

//storeResultsHandler.js
const ebayFiltering = (query, accuracy, results) => {
  return results
    ?.filter((result) => {
      const { title, condition, price } = result;
      const extractedPrice = price?.extracted;
      if (100 - levenshtein(query, title) >= accuracy && condition === "Brand New" && extractedPrice) {
        return true;
      } else return false;
    })
    ?.sort((a, b) => {
      if (a.price.extracted > b.price.extracted) return 1;
      else return -1;
    });
};

After receiving the results, the user selects those that suit him and again sends a request to the server on route "/comparison":

//index.js
app.post("/comparison", buildComparisonTable);

This time, our server, using SerpApi, searches and filters products on another site (if eBay was selected as the target site, then the search is performed on Walmart) for each product selected by the user:

//storeResultsHandler.js
export const buildComparisonTable = async (req, res) => {
  const { targetStore, selectedResults, accuracy } = req.body;
  let comparisonResults = [];
  for (const result of selectedResults) {
    const { title } = result;
    if (targetStore === "ebay") {
      const walmartResults = await getStoreResults("walmart", title);
      comparisonResults.push({ product: result, comparison: walmartFiltering(title, accuracy, walmartResults) });
    } else {
      const ebayResults = await getStoreResults("ebay", title);
      comparisonResults.push({ product: result, comparison: ebayFiltering(title, accuracy, ebayResults) });
    }
  }
  res.status(200).json({ comparisonResults });
};

The final result is returned to the user for the selection of products with the greatest benefit and the ability to save the selected products in the "xlsx" file:

image

Limitations & things to improve

Limitations:

  • You need to specify the name of the product as accurately as possible;

  • You need to choose the appropriate search results yourself;

  • Only two marketplaces are currently supported;

  • Ability to save results only in xslx format.

Things to improve:

  • Connect more marketplaces;

  • Create a PDF template to make saved results look prettier and more readable;

  • Use AI for result matching instead of levenshtein. Possibly match via images also.

If you want other functionality added to this demo project or if you want to see some other projects made with SerpApi, write me a message.


Join us on Twitter | YouTube

Add a Feature Request💫 or a Bug🐞

0
Subscribe to my newsletter

Read articles from Mikhail Zub directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Mikhail Zub
Mikhail Zub