53
Views
3
Comments
Solved
Want to get the content from the quizzes without manually copy pasting?

I wanted to get the questions from the quizzes in the Web Developer course so I could practice later, but found it a bore to manually copy and paste everything into a separate file, so I wrote this bit of JavaScript to do it for me:

getQuizContent = () => {
    const questionContainerNodeList = document.querySelectorAll('.margin-bottom-l ');
    return Array.from(questionContainerNodeList).map(containerNode => {
        return Array.from(containerNode.getElementsByClassName('quiz-question__text')).map(questionNode => {
            const question = questionNode.innerText;
            const answerNodes = container.getElementsByClassName('quiz-answer__answer');
            answers = Array.from(answerNodes).map(node => node.innerText);
            return {
                question,
                answers
            }
        })
    })
    .flat()
    .reduce(formatQuestionText, '')
}

printQuizContent()

How to use:
1. Open console (F12)

2. Paste the code


If you're reading this and have the same problem, I hope it's helpful. If it doesn't work, feel free to change it.

Rank: #1882
Solution

So, I ran this again today and it wasn't working, due to various things. (I left out some code before - not sure why I did that anymore)

Here's a complete working version. :)


getQuizContent = () => {
  if (window.DEBUG) {
    // off by default, set window.DEBUG = true to run debugger if something doesn't work
    debugger;
  }

  const questionContainerNodeList = document.querySelectorAll(
    ".margin-bottom-l "
  );
  // get all question content and format it
  return Array.from(questionContainerNodeList)
    .map((containerNode) => {
      return Array.from(
        containerNode.getElementsByClassName("quiz-question__text")
      ).map((questionNode) => {
        const question = questionNode.innerText;
        const answerNodes = containerNode.getElementsByClassName(
          "quiz-answer__answer"
        );
        answers = Array.from(answerNodes).map((node) => node.innerText);
        // format content for formatQuestionText function
        return {
          question,
          answers,
        };
      });
    })
    .flat()
    .reduce(formatQuestionText, "");
};

// Formats question content. Change this to change the format
formatQuestionText = (accumulator, currentQuestionContent, index) => {
  const paraSpace = index === 0 ? "" : "\n\n"; // only add space after first question has been added to accumulator
  return (
    accumulator +
    paraSpace +
    currentQuestionContent.question +
    "\n\n" +
    currentQuestionContent.answers.join("\n")
  );
};

getQuizContent();

Same thing as before, just copy and paste to get the text

mvp_badge
MVP
Rank: #132

Hello!

Well done.

Thanks

Rank: #1882
Solution

So, I ran this again today and it wasn't working, due to various things. (I left out some code before - not sure why I did that anymore)

Here's a complete working version. :)


getQuizContent = () => {
  if (window.DEBUG) {
    // off by default, set window.DEBUG = true to run debugger if something doesn't work
    debugger;
  }

  const questionContainerNodeList = document.querySelectorAll(
    ".margin-bottom-l "
  );
  // get all question content and format it
  return Array.from(questionContainerNodeList)
    .map((containerNode) => {
      return Array.from(
        containerNode.getElementsByClassName("quiz-question__text")
      ).map((questionNode) => {
        const question = questionNode.innerText;
        const answerNodes = containerNode.getElementsByClassName(
          "quiz-answer__answer"
        );
        answers = Array.from(answerNodes).map((node) => node.innerText);
        // format content for formatQuestionText function
        return {
          question,
          answers,
        };
      });
    })
    .flat()
    .reduce(formatQuestionText, "");
};

// Formats question content. Change this to change the format
formatQuestionText = (accumulator, currentQuestionContent, index) => {
  const paraSpace = index === 0 ? "" : "\n\n"; // only add space after first question has been added to accumulator
  return (
    accumulator +
    paraSpace +
    currentQuestionContent.question +
    "\n\n" +
    currentQuestionContent.answers.join("\n")
  );
};

getQuizContent();

Same thing as before, just copy and paste to get the text