如何优雅地从 HTML 文档中提取 JSON 数据

本文内容已假定您已拥有一些 html 以及爬虫的基础知识

需求背景

这几天在做一款资源站产品,开发过程中需要一定的测试数据,就考虑从网络中的一些网站中爬取一些,但由于用量较少不想因此去写一个爬虫,而且需要对取回的数据能快速调整转换。

市场上虽然有很多爬虫工具和开源库,但大部分用下来都觉得过于“重”了。虽然需要获取的数据较少,但要求的即时性高、数据返回格式便于调整,在试用各种工具和库的时候,发现了一款基于cherrio 封装实现的库 temme,试用之后感觉真的是神器,所以也很希望分享给大家。

temme 是一个类 jQuery 的选择器,用于简洁优雅地从 HTML 文档中提取所需的 JSON 数据。有在线版本和 vscode-temme 插件,文尾有开源库地址。

案例实践

实战一个例子体验一下:

要求如下:

从一个设计资源站 design.maliquankai.com,中提取一些 JSON 格式内容数据,网站如下:

image.png

需要将网站 html 内容提取为以下格式的数据:

  "图库": [
    {
      "cover": "images/img/pexels.jpg",
      "guid": "https://www.pexels.com",
      "description": "免费高品质图片下载网站",
      "title": "Pexels",
      "content": "提供海量共享图片素材,每周都会定量更新,所有的图片都会显示详细的信息,例如拍摄的相机型号、光圈、焦距、ISO、图片大分辨率等,高清大图质量很不错。"
    },

……

用浏览器查看网站的 html 源,它的内容格式部分如下:

<section class="scroll-floor floor2">
  <div class="case-container">
    <div class="case-index-title">
      <h2>图库网站<span class="detail">已收录36个网站</span></h2>
    </div>

    <div class="case-index-content">
      <ul class="clearfix">
        <li class="case-example-item">
          <a href="https://www.pexels.com" target="_blank">
            <img data-src="images/img/pexels.jpg" alt="" class="case-pad lozad">
            <div class="case-item-info">
              <div class="case-info-logo"><p>免费高品质图片下载网站</p></div>
              <div class="case-info-title">Pexels</div>
              <div class="case-info-text">提供海量共享图片素材,每周都会定量更新,所有的图片都会显示详细的信息,例如拍摄的相机型号、光圈、焦距、ISO、图片大分辨率等,高清大图质量很不错。
              </div>
            </div>

          </a>
        </li>
        <li class="case-example-item">
          <a href="https://pixabay.com" target="_blank">
            <img data-src="images/img/pixabay.jpg" alt="" class="case-pad lozad">
            <div class="case-item-info">
              <div class="case-info-logo"><p>1.6百万张高质量免费图像</p></div>
              <div class="case-info-title">Pixabay</div>
              <div class="case-info-text">Pixabay
                拥有超过1.6百万张高质量免费图像、矢量和视频素材,你可以复制、修改、转发等方式使用这些图像,甚至用作商业用途,无需申请许可,也无需支付版税。
              </div>
            </div>
          </a>
        </li>
        ……
      </ul>
    </div>
  </div>
</section>

需求和源都准备就绪,开始实操:

1 安装环境

# 全局安装 temme
yarn global add temme

2 编写 temme 选择器

temme 原理是根据 CSS 选择器语法从 HTML 文档/片段中抓取想要的数据。语法支持JavaScript 字面量(string/number/null/boolean/RegExp)

将下面内容,存为 selector.temme 文件

// 因为这个是可重复利用的代码,可以写成代码片断供下面抓取的语法共享使用
@contentInfo = {
  img[data-src=$cover src=$imgUrl];
  a[href=$guid];
  .case-info-logo p{$description};
  .case-info-title {$title};
  .case-info-text {$content}
};

// 这个 floor1 对应 html 文档中的 <section class="scroll-floor floor2">,由此可以分区域抓取
.floor1 li@插画{
    @contentInfo;
};

.floor2 li@图库{
    @contentInfo;
};

执行以下命令

curl -s https://design.maliquankai.com/ | temme selector.temme --format

# 输出如下:
#{
#  "插画": [
#    {
#      "cover": "images/illustration/undraw.jpg",
#      "guid": "https://undraw.co/illustrations",
#      "description": "一个扁平化插画图库",
#      "title": "unDraw",
#      "content": "unDraw是由Katerina Limpitsouni创建的一个扁平化插画图库,从网站上就可以直接调整所有插图的主要颜色,支持下载SVG和PNG格式,不需要标示出处,可用于商业用途。"
#    },
#    ……
#  ],
#  "图库": [
#    {
#      "cover": "images/img/pexels.jpg",
#      "guid": "https://www.pexels.com",
#      "description": "免费高品质图片下载网站",
#      "title": "Pexels",
#      "content": "提供海量共享图片素材,每周都会定量更新,所有的图片都会显示详细的信息,例如拍摄的相机型号、光圈、焦距、ISO、图片大分辨率等,高清大图质量很不错。"
#    },
#    ……
#  ]
#}

很好,得到了我想要的结果,那么如果还是觉得麻烦,也可以使用它的在线网站进行操作,我建议用以下几种方式使用:

1、安装全局环境,使用 tmme 命令
2、安装 VSCode 插件 vscode-temme) 在VSCode 中直接执行,可以方便抓取回的内容直接编排(👍🏻强烈推荐)
3、在自己的项目中引用

下面演示一下在 vscode 中的操作,这个是官方插件中的示例,我后面的一些使用也都基于 vscode-temme 插件,非常方便。

vscode-temme.gif

相关资料

temme 源码库 https://github.com/shinima/temme

常用爬虫库
https://scrapy.org/
https://github.com/cheeriojs/cheerio
https://github.com/puppeteer/puppeteer
thal

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容