Более оптимизированная альтернатива повторным вызовам API выборки для сбора данных с нескольких веб-страниц одного домена - PullRequest
0 голосов
/ 05 февраля 2019

Я работаю над расширением Google Chrome, целью которого является сбор всех отзывов пользователей Amazon для любого конкретного продукта, указанного на Amazon.com или Amazon.co.uk для манипулирования.Не все отзывы Amazon хранятся под одним URL;вместо этого Amazon перечисляет до 10 ревивов на страницу .Первоначальная мысль, которая у меня возникла в связи с этим, заключалась в том, чтобы использовать API выборки, чтобы собрать 10 обзоров на определенной странице, добавить их в массив, прежде чем перейти к следующей странице, и остановить, когда следующая страница не определена.Единственная проблема заключается в том, что для этого может потребоваться сотни вызовов API выборки для каждого продукта, что занимает много времени.

let contentArray = [];
let reviewArray = [];

function collectProductComments(){
  let parser = new DOMParser();
  let url = document.getElementsByClassName("a-link-emphasis")[0].href;

  getFirstTen(url, parser);
}

function getFirstTen(url, parser){ //function for the collection of the initial 10 elements containing a user review of a specific product
  if(isGood(url)){
    fetch(url)  //fetches data from page specified by 'url' variable
      .then(response => response.text())  //Specify response as text
      .then(data => {
        console.log("Collecting reviews...");
        let doc = parser.parseFromString(data, "text/html");  //Parse response to DOM
        for(let i = 0 ; i < doc.getElementsByClassName("review").length ; i++){
          reviewArray.push(doc.getElementsByClassName("review")[i]);  //Iterate through reviews, append them to array
        }
        if(doc.getElementById("cm_cr-pagination_bar") != undefined){  //check if "next page" button exists
          nextURL(doc); //handle next pages.
        }else{
          collectionResolved(); //If no "next page" button exists, treat as though all reviews have been collected.
        }
      })
      .catch(function(error) {
        console.log(error);
      });
  }
}

function nextURL(doc, parser){
  url = doc.getElementById("cm_cr-pagination_bar").children[0].lastChild.children[0].href;  //Get URL of the page containing the next 10 reviews
  if (isGood(url)){ //If the next page exists....
    fetch(url)
      .then(response => response.text())  //Specify response as text
      .then(data => {
        doc = parser.parseFromString(data, "text/html"); //Parse response as DOM
        for(let i = 0 ; i < doc.getElementsByClassName("review").length ; i++){
          reviewArray.push(doc.getElementsByClassName("review")[i]);         //Iterate through reviews, append them to array
        }
        nextURL(doc); //Assume there is a next page
      })
      .catch(function(error) {
        console.log(error);
      });
  }
  else{ //This is fired when there is no next page to check
    collectionResolved(); //treat as though all reviews have been collected
  }
}

function collectionResolved(){
  console.log("Review collection resolved.");
  contentArray = handleReviews(reviewArray); //Logic for searching through the DOM of the reviews.
  console.log(contentArray);
  saveReviews(contentArray);
}

function isGood(url){
  if (url == undefined){
    return false;
  }else{return true;}
}

function handleReviews(elementsToCheck){
  let tempContentArray = [];
  for(let i = 0 ; i < elementsToCheck.length ; i++){
    tempContentArray[i] = [getUser(elementsToCheck[i]), getTitle(elementsToCheck[i]), getComment(elementsToCheck[i])]; //Dissect each review DOM element into appropriate text.
  }
  return tempContentArray;
}

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

Кто-нибудь знает какой-либо метод, который можно использовать либо для оптимизации этого кода, либо для создания превосходного метода достижения того же результата?

...