亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Nodejs解析網(wǎng)站網(wǎng)址內(nèi)容并獲取標(biāo)題圖標(biāo)

 更新時間:2024年11月26日 09:39:15   作者:XY筆記  
cheerio類似于jQuery的API,讓我們可以方便地操作HTML文檔,下面我們就來看看在Node.js中如何借助cheerio庫高效地解析和提取HTML內(nèi)容吧

介紹

在很多應(yīng)用場景中,我們需要從一個網(wǎng)頁中提取信息,比如標(biāo)題(title)、網(wǎng)站圖標(biāo)(favicon)以及簡介(description)。這些信息常用于以下場景:

分享功能:當(dāng)用戶在社交平臺分享鏈接時,展示鏈接的標(biāo)題、縮略圖和描述內(nèi)容。

數(shù)據(jù)抓?。河糜诜治鼍W(wǎng)頁信息,生成報告或構(gòu)建爬蟲應(yīng)用。

預(yù)覽功能:為用戶提供鏈接的簡要信息,提升交互體驗。

在Node.js中,可以借助cheerio庫高效地解析和提取HTML內(nèi)容。cheerio類似于jQuery的API,讓我們可以方便地操作HTML文檔,而無需啟動瀏覽器環(huán)境(如Puppeteer)。

代碼實現(xiàn)

異步獲取指定URL的內(nèi)容

代碼定義了一個異步函數(shù) fetchUrlContent,用于獲取指定 URL 的內(nèi)容。主要功能如下:

  • 發(fā)送 HEAD 請求:首先發(fā)送一個 HEAD 請求來獲取響應(yīng)頭信息,檢查內(nèi)容長度是否超過限制。
  • 檢查內(nèi)容長度:如果內(nèi)容長度超過限制,記錄日志并返回錯誤。
  • 檢查內(nèi)容類型:如果內(nèi)容類型是 HTML,則發(fā)送 GET 請求獲取實際內(nèi)容。
  • 再次檢查內(nèi)容長度:在獲取到實際內(nèi)容后,再次檢查內(nèi)容長度是否超過限制。
  • 記錄日志并返回結(jié)果:如果一切正常,記錄日志并返回內(nèi)容;否則記錄錯誤并拋出異常。
/**
 * 異步獲取指定URL的內(nèi)容
 * 該函數(shù)首先發(fā)送一個HTTP HEAD請求,以檢查URL的內(nèi)容類型和大小
 * 如果內(nèi)容類型為HTML且大小在允許范圍內(nèi),則進一步發(fā)送GET請求獲取實際內(nèi)容
 *
 * @param url 目標(biāo)URL地址
 * @returns Promise對象,解析后返回URL的內(nèi)容,如果發(fā)生錯誤則拒絕Promise
 */
export async function fetchUrlContent(url: string) {
  return axios
    .head(url, {
      validateStatus: () => true,
      maxContentLength: configs.FETCH_URL_INFO.MAX_RESPONSE_SIZE,
      headers: {
        'Content-Type': 'charset:utf-8',
        Accept: 'application/json, text/plain, */*',
        'accept-encoding': 'gzip, deflate, br'
      },
      timeout: configs.FETCH_URL_INFO.TIMEOUT
    })
    .then((res) => {
      // 檢查內(nèi)容大小是否超出限制
      if (res?.headers?.['content-length'] && parseInt(res?.headers['content-length']) > configs.FETCH_URL_INFO.MAX_RESPONSE_SIZE) {
        logger.log('[url] 限制:', url, res?.headers['content-length'], res?.headers['content-type']);
        return Promise.reject(new CustomError('URL_CONTENT_ERROR', '不支持該url內(nèi)容解析'));
      }
      // 檢查內(nèi)容類型是否為HTML
      if (res?.headers['content-type']?.includes('text/html')) {
        return axios
          .get(url, { headers: { accept: 'text/html', 'Content-Type': 'text/html;charset:utf-8', 'User-Agent': configs.FETCH_URL_INFO.USER_AGENT }, timeout: configs.FETCH_URL_INFO.TIMEOUT })
          .then((res) => {
            if (res) {
              logger.log('[url] 爬取成功 axios', url);
              // 再次檢查內(nèi)容大小是否超出限制
              if (res.data?.length > configs.FETCH_URL_INFO.MAX_RESPONSE_SIZE) {
                logger.log('[url] buffer大小: ', url, res.data?.length);
                return Promise.reject(new CustomError('URL_CONTENT_ERROR', '內(nèi)容過大解析失敗'));
              }
              return res.data;
            }
            return Promise.reject(res);
          })
          .catch((e) => {
            logger.error('[url] fetch get', url, e.message);
            throw new CustomError('URL_GET_FETCH_ERROR', '不支持該url內(nèi)容解析');
          });
      }
      return Promise.reject(new CustomError('URL_UNVALID_ERROR', '不支持該url內(nèi)容解析'));
    })
    .catch((e) => {
      logger.error('[url] fetch head', url, e.message);
      throw new CustomError('URL_HEAD_FETCH_ERROR', '不支持該url內(nèi)容解析');
    });
}

解析網(wǎng)址內(nèi)容

具體實現(xiàn)

/**
 * 解析URL內(nèi)容
 * @param url 頁面URL
 * @param html 頁面HTML內(nèi)容
 * @returns 返回包含URL、圖標(biāo)、簡介和標(biāo)題的對象
 */
export async function parseUrlContent(url: string, html: string): Promise<{ url: string; icon: string; intro: string; title: string }> {
  const $ = load(html);

  let title = '';
  let intro = '';
  let icon = '';

  // 獲取標(biāo)題節(jié)點
  const titleEl = $('title');
  if (titleEl?.text()) {
    title = titleEl?.text();
  }

  // 獲取icon
  const linkEl = $('link');
  const links: string[] = [];
  if (linkEl) {
    linkEl.each((_i, el) => {
      const rel = $(el).attr('rel');
      const href = $(el).attr('href');
      if (rel?.includes('icon') && href) {
        links.push(href);
      }
    });
  }
  logger.log('[url] 獲取icon', links);
  if (links.length) {
    icon = resolveUrl(url, links[0]);
  }

  /**
   * 獲取meta屬性
   * @param metaElement
   * @param name
   * @returns
   */
  const getPropertyContent = (Element, name: string) => {
    const propertyName = $(Element)?.attr('property') || $(Element)?.attr('name');
    return propertyName === name ? $(Element)?.attr('content') || '' : '';
  };

  // 獲取詳情
  const metas = $('meta');
  for (const meta of metas) {
    if (title && intro) {
      break;
    }
    // 如果沒有標(biāo)題
    if (!title) {
      const titleoAttr = ['og:title', 'twitter:title'];
      for (const attr of titleoAttr) {
        const text = getPropertyContent(meta, attr);
        if (text) {
          title = text;
          break;
        }
      }
    }

    // 簡介
    if (!intro) {
      const introAttr = ['description', 'og:description', 'twitter:description'];
      for (const attr of introAttr) {
        const description = getPropertyContent(meta, attr);
        if (description) {
          intro = description;
          break;
        }
      }
    }

    // icon
    if (!icon) {
      const imageAttr = ['og:image', 'twitter:image'];
      for (const attr of imageAttr) {
        const image = getPropertyContent(meta, attr);
        if (image) {
          intro = resolveUrl(url, image);
          break;
        }
      }
    }
  }
  // 沒有簡介提取全部
  if (!intro) {
    const body = $('body').html();
    intro = body ? htmlStringReplace(body, configs.FETCH_URL_INFO.MAX_INTRO_LENGTH) : '';
  }
  logger.log('[url] 爬取結(jié)果', { url, title, intro, icon });
  return {
    url,
    title: title?.trim() || '',
    intro: intro?.trim() || '',
    icon
  };
}

代碼解釋

這段 TypeScript 代碼定義了一個異步函數(shù) parseUrlContent,用于解析 HTML 內(nèi)容并提取 URL 的標(biāo)題、圖標(biāo)、簡介和原始 URL。具體步驟如下:

  • 加載 HTML:使用 load 函數(shù)加載傳入的 HTML 字符串。
  • 獲取標(biāo)題:從 <title> 標(biāo)簽中提取頁面標(biāo)題。
  • 獲取圖標(biāo):從 <link> 標(biāo)簽中提取 favicon 圖標(biāo)。
  • 獲取元數(shù)據(jù):定義一個輔助函數(shù) getPropertyContent 用于從 <meta> 標(biāo)簽中提取特定屬性的內(nèi)容。
  • 提取詳情:從 <meta> 標(biāo)簽中提取標(biāo)題、簡介和圖標(biāo)。
  • 處理簡介:如果沒有提取到簡介,則從 <body> 中提取部分內(nèi)容作為簡介。

開發(fā)API的用法

接口地址

// js演示
var axios = require('axios');
var data = JSON.stringify({
  url: 'https://xygeng.cn/post/200'
});

// 注意只支持post請求
var config = {
  method: 'post',
  url: 'https://api.xygeng.cn/openapi/url/info',
  headers: {
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36',
    'Content-Type': 'application/json',
    Accept: '*/*',
    Connection: 'keep-alive'
  },
  data: data
};

axios(config)
  .then(function (response) {
    console.log(JSON.stringify(response.data));
  })
  .catch(function (error) {
    console.log(error);
  });

到此這篇關(guān)于Nodejs解析網(wǎng)站網(wǎng)址內(nèi)容并獲取標(biāo)題圖標(biāo)的文章就介紹到這了,更多相關(guān)Nodejs解析網(wǎng)站網(wǎng)址內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • node中使用shell腳本的方法步驟

    node中使用shell腳本的方法步驟

    這篇文章主要介紹了node中使用shell腳本的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • webpack打包、編譯、熱更新Node內(nèi)存不足問題解決

    webpack打包、編譯、熱更新Node內(nèi)存不足問題解決

    Webpack是現(xiàn)在主流的功能強大的模塊化打包工具,在使用Webpack時,如果不注意性能優(yōu)化,有非常大的可能會產(chǎn)生性能問題,下面這篇文章主要給大家介紹了關(guān)于webpack打包、編譯、熱更新Node內(nèi)存不足問題解決的相關(guān)資料,需要的朋友可以參考下
    2023-03-03
  • 詳解如何在NodeJS應(yīng)用程序中處理多個API請求

    詳解如何在NodeJS應(yīng)用程序中處理多個API請求

    NodeJS默認(rèn)是異步的,這意味著它已經(jīng)能夠同時處理多個請求,但它只適用于I/O操作,如HTTP請求、文件系統(tǒng)操作、數(shù)據(jù)庫查詢、實時聊天應(yīng)用等,在處理CPU密集型任務(wù)時,可能需要很長時間,這就是為什么NodeJS提供了一些我們將在下面介紹的特定包
    2023-12-12
  • 在 Node.js 中使用原生 ES 模塊方法解析

    在 Node.js 中使用原生 ES 模塊方法解析

    這篇文章主要介紹了在 Node.js 中使用原生 ES 模塊方法解析,還有部分內(nèi)容的鏈接,下面我們就來一起看看吧,需要的朋友可以參考下。
    2017-09-09
  • 了不起的node.js讀書筆記之node的學(xué)習(xí)總結(jié)

    了不起的node.js讀書筆記之node的學(xué)習(xí)總結(jié)

    這篇文章主要介紹了了不起的node.js讀書筆記之node的學(xué)習(xí)總結(jié),需要的朋友可以參考下
    2014-12-12
  • nodejs個人博客開發(fā)第六步 數(shù)據(jù)分頁

    nodejs個人博客開發(fā)第六步 數(shù)據(jù)分頁

    這篇文章主要為大家詳細(xì)介紹了nodejs個人博客開發(fā)的數(shù)據(jù)分頁,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • 一文教會你從Windows中完全刪除node.js

    一文教會你從Windows中完全刪除node.js

    作為新手nodejs卸載后安裝就總出錯,下面這篇文章主要給大家介紹了關(guān)于如何從Windows中完全刪除node.js的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08
  • nodejs 實現(xiàn)釘釘ISV接入的加密解密方法

    nodejs 實現(xiàn)釘釘ISV接入的加密解密方法

    這篇文章主要介紹了nodejs 實現(xiàn)釘釘ISV接入的加密解密方法,非常不錯,具有參考借鑒價值,需要的的朋友參考下吧,需要的朋友可以參考下
    2017-01-01
  • nodejs實現(xiàn)jwt的示例代碼

    nodejs實現(xiàn)jwt的示例代碼

    本文主要介紹了nodejs實現(xiàn)jwt的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • node使用promise替代回調(diào)函數(shù)

    node使用promise替代回調(diào)函數(shù)

    這篇文章主要介紹了node使用promise替代回調(diào)函數(shù),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05

最新評論