Где все действительно идет не так, как надо

Это вторая часть моего погружения в безумие, в которой я взял задачу электронной коммерции, которая могла занять 20 минут, и превратила ее в задачу кодирования, на которую ушли часы. Если вы еще не ознакомились с частью 1, вернитесь и сначала прочтите ее, чтобы решить, действительно ли вы хотите это сделать.

Вот что я уже обсуждал:

  1. На мой взгляд, этот сайт электронной коммерции слишком медленный. Маяк соглашается.
  2. Я решил сделать простое приложение на Node.js, чтобы добавлять несколько товаров в корзину, чтобы мне не приходилось добавлять их по одному.
  3. Я использую инструменты разработчика Chrome для проверки сетевых запросов. Я просматриваю множество запросов, пока не найду тот, который добавляет товар в корзину.
  4. Я добавляю товар в корзину с помощью запроса POST в инструментах разработчика для подтверждения концепции.
  5. Я воссоздаю этот пост-запрос в приложении Node.js, используя puppeteer для управления браузером Chrome.
  6. Как только все товары будут добавлены в корзину, у меня откроется окно браузера с корзиной, чтобы я мог оформить заказ и совершить покупку.

Как найти этот надоедливый идентификатор атрибута

Честно говоря, я не знаю, зачем каждому цвету нити нужен как идентификатор продукта, так и идентификатор атрибута. Поскольку каждое из этих значений уникально для цвета, наличие обоих кажется чрезмерным.

Может мне это не нужно?

Моя первая мысль заключалась в том, что, возможно, мне не нужен правильный идентификатор атрибута, чтобы добавить товар в корзину. К сожалению, идентификатор атрибута должен быть включен и точен, чтобы добавить поток в корзину через запрос API.

Хорошо, мне это нужно. Может по запросу найду?

Я надеялся, что был какой-то запрос, который вытащил идентификатор атрибута продукта, но, к сожалению, его нет.

Может, найду на страничке?

Его даже нет нигде в HTML страницы с шестью нитями.

Хорошо, этого нет на странице. Было весело, но, может быть, пора упаковать вещи.

На данный момент я потратил на этот проект больше времени, чем хотел бы признаться. Я знаю, что этот идентификатор атрибута должен существовать где-то на этом веб-сайте, потому что он каким-то образом доступен для добавления в форму при добавлении цвета в корзину. Путем проб и ошибок я наконец нашел идентификатор атрибута. Когда вы ищете цвет по его идентификатору продукта, вы получаете изображение цвета. Когда вы просматриваете изображение, вы можете увидеть идентификатор атрибута данных.

Еще один запрос POST! Ура!

Подобно добавлению товара в корзину, поиск данного товара является запросом POST. Я использовал тот же процесс, что и раньше, чтобы найти конечную точку REST:

  1. Откройте инструменты разработчика в Chrome
  2. Поиск цвета по идентификатору продукта
  3. Проверьте сетевые вызовы, чтобы определить, какой из них нужно искать
  4. Проверить результаты поиска по идентификатору атрибута
let url = “https://www.dmc.com/js/ajax/prod_module.php"; // “search” endpoint
const produit_id = 9003292; // id for all 6 string threads
let colorSearchFormData = new FormData();
colorSearchFormData.append(“module”, “couleur”);
colorSearchFormData.append(“produit_id”, produit_id);
colorSearchFormData.append(“produit_option_valeur_ref”, produit_ref);
colorSearchFormData.append(“last_step”, 1);
colorSearchFormData.append(“searchRefColor”, 1);
colorSearchFormData.append(“color_parent_search[]”, 7477);
console.log(“fetching search results”);
const result = await fetch(url, { method: “POST”, body: colorSearchFormData })
  .then(response => {
    return response.json();
  });
  
// parse result as HTML const doc = new DOMParser().parseFromString(
  result.preview_selected_search,
  “text/html”
);
// find desired tag and get value. This is the attribute id for the searched color
const prod_attribut = doc
  .querySelector(“.add-product.disabled”)
  .getAttribute(“data-attribut”);

Я потерялся

Я тоже, друг, я тоже. Это путешествие не для слабонервных. Или для людей, которые не любят тратить время на бессмысленные программные проекты. К счастью, я обновил удобную диаграмму, чтобы показать процесс:

Все вместе сейчас

Собирая все вместе, вот полный пример кода:

const puppeteer = require(“puppeteer”);
(async () => {
  const browser = await puppeteer.launch({ headless: false });
  const page = await browser.newPage();
  console.log(“navigating to home page”);
  
  await page.goto(“https://www.dmc.com/us/");
  let default_quanity = 2;
  const produit_refs = [
    { id: “BLANC” },
    { id: 221 },
    { id: 3340 },
    { id: 825 },
    { id: 321 }
  ];
  for (ref of produit_refs) {
    console.log(ref);
    await addToCart(page, ref.id, ref.quantity || default_quanity);
  }
 
  console.log(“navigating to shopping cart… … …”);
  await page.goto(“https://www.dmc.com/us/shopping_cart.html");
})();
async function addToCart(page, produit_ref, quantity) {
  // adds color to shopping cart
  console.log(“adding color to cart”);
  const addToCart = await page.evaluate(async (produit_ref, quantity) => {
    let url = “https://www.dmc.com/js/ajax/prod_module.php";
    const produit_id = 9003292;
    let colorSearchFormData = new FormData();
    colorSearchFormData.append(“module”, “couleur”);
    colorSearchFormData.append(“produit_id”, produit_id);
    colorSearchFormData.append(“produit_option_valeur_ref”, produit_ref);
    colorSearchFormData.append(“last_step”, 1);
    colorSearchFormData.append(“searchRefColor”, 1);
    colorSearchFormData.append(“color_parent_search[]”, 7477); 
    console.log(“fetching search results”);
    const result = await fetch(url, { method: “POST”, body: colorSearchFormData })
      .then(response => {
        return response.json();
      });
    const doc = new DOMParser().parseFromString(
      result.preview_selected_search,
      “text/html”
    );
    const prod_attribut = doc
      .querySelector(“.add-product.disabled”)
      .getAttribute(“data-attribut”);
   
    url = “https://www.dmc.com/js/ajax/update-panier.php";
    let addToCartFormData = new FormData();
    addToCartFormData.append(“produit_id”, produit_id);
    addToCartFormData.append(“produit_ref”, produit_ref);
    addToCartFormData.append(“produit_attribut_id”, prod_attribut);
    addToCartFormData.append(“quantite”, quantity);
    addToCartFormData.append(“action”, “add”);
    return await fetch(url, { method: “POST”, body: addToCartFormData });
  },
  produit_ref,
  quantity
  );
 }

Вот и все! Простой. Но если не считать шуток, я все же планирую использовать этот код. Я заказываю нитки нескольких цветов одновременно. Например, мой последний заказ был примерно 30 разных цветов. Если я воспользуюсь этим кодом для покупки треда еще пару раз, я думаю, что окуплю потраченное время.

Хотели бы вы, чтобы я создавал больше бесполезных проектов по программированию? Есть какие-нибудь глупые проекты, которыми вы хотели бы поделиться? Дайте мне знать, что вы хотите увидеть! Прокомментируйте здесь или напишите мне в Twitter!