109 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
			
		
		
	
	
			109 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
import browser from "../system/browser.js";
 | 
						|
import { extractModelId, extractNumber } from "../system/ultils.js";
 | 
						|
import { ScrapModel } from "./scrap-model.js";
 | 
						|
 | 
						|
export class PicklesScrapModel extends ScrapModel {
 | 
						|
  action = async () => {
 | 
						|
    const urlsData = this.extractUrls();
 | 
						|
 | 
						|
    for (let item of urlsData) {
 | 
						|
      await this.page.goto(item.url);
 | 
						|
 | 
						|
      const data = await this.getItemsInHtml(item);
 | 
						|
 | 
						|
      const results = this.filterItemByKeyword(item.keyword, data);
 | 
						|
 | 
						|
      this.results[item.keyword] = results;
 | 
						|
 | 
						|
      console.log({ results: this.results });
 | 
						|
    }
 | 
						|
  };
 | 
						|
 | 
						|
  async getPrice(url) {
 | 
						|
    const newPage = await browser.newPage(); // cần truyền 'url' từ bên ngoài nếu chưa có
 | 
						|
 | 
						|
    try {
 | 
						|
      await newPage.goto(`${this.web_bid.origin_url}${url}`, {
 | 
						|
        waitUntil: "domcontentloaded", // hoặc "networkidle2" nếu cần đợi AJAX
 | 
						|
      });
 | 
						|
 | 
						|
      await newPage.waitForSelector("#bidPrefix > span.font-weight-bold", {
 | 
						|
        timeout: 10000,
 | 
						|
      });
 | 
						|
 | 
						|
      const priceText = await newPage
 | 
						|
        .$eval("#bidPrefix > span.font-weight-bold", (el) =>
 | 
						|
          el.textContent.trim()
 | 
						|
        )
 | 
						|
        .catch(() => null);
 | 
						|
 | 
						|
      return extractNumber(priceText) || 0;
 | 
						|
    } catch (error) {
 | 
						|
      console.error(`Error getting price for ${url}:`, error);
 | 
						|
      return 0;
 | 
						|
    } finally {
 | 
						|
      await newPage.close();
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  getPriceByEl = async (elementHandle, model) => {
 | 
						|
    try {
 | 
						|
      const priceText = await elementHandle
 | 
						|
        .$eval(`#ps-bg-buy-btn-${model} .pds-button-label`, (el) =>
 | 
						|
          el.textContent.trim()
 | 
						|
        )
 | 
						|
        .catch(() => null);
 | 
						|
 | 
						|
      return extractNumber(priceText) || 0;
 | 
						|
    } catch (error) {
 | 
						|
      return 0;
 | 
						|
    }
 | 
						|
  };
 | 
						|
 | 
						|
  getItemsInHtml = async (data) => {
 | 
						|
    await this.page.waitForSelector(
 | 
						|
      ".content-wrapper_contentgridwrapper__3RCQZ > div.column",
 | 
						|
      {
 | 
						|
        timeout: 10000,
 | 
						|
      }
 | 
						|
    );
 | 
						|
 | 
						|
    const elements = await this.page.$$(
 | 
						|
      ".content-wrapper_contentgridwrapper__3RCQZ > div.column"
 | 
						|
    );
 | 
						|
    const results = [];
 | 
						|
 | 
						|
    for (const el of elements) {
 | 
						|
      const url = await el
 | 
						|
        .$eval("main > a", (el) => el.getAttribute("href"))
 | 
						|
        .catch(() => null);
 | 
						|
 | 
						|
      const image_url = await el
 | 
						|
        .$eval("div > div:first-child > div > div:first-child > img", (img) =>
 | 
						|
          img.getAttribute("src")
 | 
						|
        )
 | 
						|
        .catch(() => null);
 | 
						|
 | 
						|
      const name = await el
 | 
						|
        .$eval("header > h2:first-of-type", (el) => el.textContent.trim())
 | 
						|
        .catch(() => null);
 | 
						|
 | 
						|
      const model = extractModelId(`${this.web_bid.origin_url}${url}`);
 | 
						|
 | 
						|
      const current_price = await this.getPriceByEl(el, model);
 | 
						|
 | 
						|
      results.push({
 | 
						|
        url: `${this.web_bid.origin_url}${url}`,
 | 
						|
        image_url,
 | 
						|
        name,
 | 
						|
        keyword: data.keyword,
 | 
						|
        model,
 | 
						|
        current_price: current_price,
 | 
						|
        scrap_config_id: this.scrap_config_id,
 | 
						|
      });
 | 
						|
    }
 | 
						|
 | 
						|
    return results;
 | 
						|
  };
 | 
						|
}
 |