最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

介紹

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

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

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

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

在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 請求來獲取響應頭信息,檢查內(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 目標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、圖標、簡介和標題的對象
 */
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 = '';

  // 獲取標題節(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;
    }
    // 如果沒有標題
    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 的標題、圖標、簡介和原始 URL。具體步驟如下:

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

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

相關文章

  • Node.js?中?fs?模塊的高級用法實例詳解

    Node.js?中?fs?模塊的高級用法實例詳解

    文章介紹了Node.js中fs模塊的高級用法,包括流式讀寫、文件監(jiān)視、PromiseAPI、遞歸目錄操作等,這些功能有助于更好地處理復雜文件操作場景,提升代碼性能和可維護性,感興趣的朋友跟隨小編一起看看吧
    2025-02-02
  • nodejs服務搭建教程 nodejs訪問本地站點文件

    nodejs服務搭建教程 nodejs訪問本地站點文件

    這篇文章主要為大家詳細介紹了nodejs服務搭建教程,訪問本地站點文件,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • 詳解在express站點中使用ejs模板引擎

    詳解在express站點中使用ejs模板引擎

    本篇文章主要介紹了在express站點中使用ejs模板引擎,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • 快速搭建Node.js(Express)用戶注冊、登錄以及授權的方法

    快速搭建Node.js(Express)用戶注冊、登錄以及授權的方法

    這篇文章主要介紹了快速搭建Node.js(Express)用戶注冊、登錄以及授權,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-05-05
  • webstorm中配置nodejs環(huán)境及npm的實例

    webstorm中配置nodejs環(huán)境及npm的實例

    今天小編就為大家分享一篇webstorm中配置nodejs環(huán)境及npm的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05
  • Node.js實現(xiàn)斷點續(xù)傳

    Node.js實現(xiàn)斷點續(xù)傳

    上傳圖片、Excel等,畢竟幾M的大小可以很快就上傳到服務器。 針對于上傳視頻等大文件幾百M或者幾G的大小,就需要等待比較長的時間。這就產(chǎn)生了對應的解決方法,對于大文件上傳時的暫停、斷網(wǎng)、網(wǎng)絡較差的情況下, 使用切片+斷點續(xù)傳就能夠很好的應對上述的情況
    2021-06-06
  • 在node中如何使用 ES6

    在node中如何使用 ES6

    這篇文章主要介紹了在node中如何使用 ES6 ,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-04-04
  • 查詢Node.js版本信息的六種方法

    查詢Node.js版本信息的六種方法

    隨著應用程序規(guī)模越來越龐大,Node.js版本的更新也日益頻繁,本文主要介紹了查詢Node.js版本信息的六種方法,具有一定的參考價值,感興趣的可以了解一下
    2024-03-03
  • 關于在mongoose中填充外鍵的方法詳解

    關于在mongoose中填充外鍵的方法詳解

    在學習非關系型數(shù)據(jù)庫mongoDB,希望能夠完成數(shù)據(jù)庫的CRUD,采用的是JS做的后臺,因此用到了mongoose,下面這篇文章主要給大家介紹了關于在mongoose中填充外鍵的相關資料,文中介紹的非常詳細,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-08-08
  • node安裝--linux下的快速安裝教程

    node安裝--linux下的快速安裝教程

    本篇文章主要介紹了node安裝--linux下的快速安裝教程,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03

最新評論

错那县| 周宁县| 桃江县| 璧山县| 铜山县| 文登市| 建宁县| 潮安县| 余庆县| 祥云县| 尉犁县| 太谷县| 鹿泉市| 元江| 广灵县| 西贡区| 邻水| 宿迁市| 双牌县| 理塘县| 徐州市| 玉门市| 陈巴尔虎旗| 苗栗县| 忻州市| 博罗县| 当雄县| 长治市| 清丰县| 聊城市| 德兴市| 万载县| 集安市| 东至县| 乐安县| 平原县| 潮安县| 根河市| 贵南县| 卓尼县| 玉树县|