Как я могу получить полный текст заголовка из Google Scholar с помощью Cheerio?

Я использую axios для отправки запроса на получение в Google Scholar. С cheerio я получаю доступ к данным. Когда название слишком длинное, я получаю: заголовок: «Сравнение дефектов при рождении живым после стимуляции яичников в лютеиновой фазе и обычной стимуляции яичников для экстракорпорального оплодотворения и переноса витрифицированных эмбрионов…».

Это код:

const free_proxy_url1 = "https://free-proxy-list.net";

request(free_proxy_url1, (err, response, body) => {
  let $ = cheerio.load(body);
  let ipResults = [];

  $(".table-responsive > div > table > tbody > tr").each(
    (i, el) => {
      if ($(el).find("td:nth-child(7)").text() === "yes")
        ipResults.push({
          ip: $(el).find("td:nth-child(1)").text(),
          port: Number($(el).find("td:nth-child(2)").text()),
          https: $(el).find("td:nth-child(7)").text(),
        });
    }
  );

  let rand = Math.floor(Math.random() * ipResults.length);
  let searchTerm = "AI";
  const proxy = {
    host: ipResults[rand].ip,
    port: ipResults[rand].port,
  };

  axios
    .get(
      `https://scholar.google.com/scholar?q=${searchTerm}`,
      proxy
    )
    .then(result => {
      const $ = cheerio.load(result.data);
      $("div.gs_ri").each((i, el) => {
        const yearElement = $(el).find("div.gs_a");
        const yearText = yearElement.text().match(/\d{4}/);
        const titleElement = $(el).find("h3.gs_rt a");
        scholar_results.push({
          title: titleElement.text().trim(),
          link: $(el).find(".gs_rt a").attr("href"),
          year: yearText ? parseInt(yearText[0]) : null,
        });
      });
    })
    .catch(err => {
      console.info(err);
    });
});

Есть ли способ получить полное название, а не усеченное?

Я редактирую его с полной функцией запроса, которую использую для получения прокси. Вы также можете запустить его без прокси-объекта, если хотите.

Paris 09.04.2023 22:35

Заголовки отсутствуют на запрашиваемом вами статическом сайте. Они могут быть в другом месте в Google Scholar, или вы можете попробовать проанализировать их из произвольного HTML для каждого URL-адреса статьи. Кстати, я не думаю, что ваш прокси применяется правильно. Думаю так и должно быть axios.get(url, {proxy: {host: "xxxx", port: 80}}).

ggorlen 12.04.2023 18:50
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
2
87
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это немного сложно. Полного названия нет нигде в статическом HTML, поэтому, похоже, вам нужно перейти по ссылке на внешний сайт для каждой статьи, а затем попытаться угадать, что это за заголовок.

Вот пример:

const axios = require("axios");
const cheerio = require("cheerio"); // 1.0.0-rc.12

const ua =
  "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36";

const normalizeText = s =>
  s.toLowerCase()
  .replace(/[^a-z]/g, " ")
  .replace(/\s+/, " ")
  .trim();

const tryFindingFullTitle = async (title, link) => {
  const normalizedTitle = normalizeText(title);

  try {
    const {data} = await axios.get(link, {headers: {"User-Agent": ua}});
    const $ = cheerio.load(data);
    return [...$("*")]
      .flatMap(e =>
        [...$(e).contents()].filter(e => e.type === "text")
      )
      .map(e => $(e).text().trim())
      .filter(Boolean)
      .find(e => normalizeText(e).startsWith(normalizedTitle));
  }
  catch (err) {
    return title;
  }
};

const runSearch = async searchTerm => {
  const url = `https://scholar.google.com/scholar?q=${encodeURI(searchTerm)}`;
  const {data} = await axios.get(url, {headers: {"User-Agent": ua}});
  const $ = cheerio.load(data);
  const result = [];

  for (const el of [...$("div.gs_ri")]) {
    const link = $(el).find(".gs_rt a").attr("href");
    const year = $(el).find("div.gs_a").text().match(/\d{4}/);
    const title = $(el).find("h3.gs_rt a").text().trim();
    result.push({
      title: title.includes("…") ?
        await tryFindingFullTitle(title, link) : title,
      link,
      year: year ? parseInt(year[0]) : null,
    });
  }

  return result;
};

runSearch("AI")
  .then(result => console.info(result))
  .catch(err => console.error(err.message));

Основная часть работы — это tryFindingFullTitle, который берет сокращенный заголовок и URL-адрес, переходит к URL-адресу и пытается найти первый элемент с текстовым содержимым, который имеет сокращенный заголовок в качестве префикса. Другой подход может состоять в том, чтобы найти текст с наименьшим расстоянием Левенштейна.

Это работает нормально для нескольких списков ScienceDirect в тестовом образце, но, вероятно, потерпит неудачу в других случаях, так что считайте это доказательством концепции. Я не знаком с этим сайтом, поэтому вполне возможно, что он полностью доступен в предсказуемом формате на другой странице Академии Google.

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

axios.get(url, {proxy: {host: "xxxx", port: 80}})

Другие вопросы по теме