【sgExcelGrid】自定义组件:简单模拟Excel表格拖拽、选中单元格、横行、纵列、拖拽圈选等操作

简介: 【sgExcelGrid】自定义组件:简单模拟Excel表格拖拽、选中单元格、横行、纵列、拖拽圈选等操作


特性:

  1. 可以自定义拖拽过表格
  2. 可以点击某个表格,拖拽右下角小正方形进行任意方向选取单元格
  3. 支持选中某一行、列
  4. 支持监听@selectedGrids、@selectedDatas事件获取选中项的DOM对象和数据数组
  5. 支持props自定义显示label字段别名

sgExcelGrid源码

<template>
  <div :class="$options.name">
    <div class="ruler-corner"></div>
    <div class="horizontal-ruler" :style="{ left: `${-rulerPosition.x}px` }">
      <div
        class="tick"
        :hoverGrid="hoverGrid.x === A_Z[i]"
        @click="(hoverGrid = { x: A_Z[i] }), (mousedownGrid = {})"
        v-for="(a, i) in A_Z.slice(0, colCount_)"
        :key="i"
      >
        {{ a }}
      </div>
    </div>
    <div class="vertical-ruler" :style="{ top: `${-rulerPosition.y}px` }">
      <div
        class="tick"
        :hoverGrid="hoverGrid.y === i"
        @click="(hoverGrid = { y: i }), (mousedownGrid = {})"
        v-for="(a, i) in Math.ceil(pageSize / colCount_)"
        :key="i"
      >
        {{ i + 1 }}
      </div>
    </div>
    <div class="grids-scroll" ref="scrollContainer">
      <div class="grids" ref="dragContainer" :selectedGrids="selectedGrids.length > 0">
        <div
          class="grid"
          :hoverGridX="hoverGrid.x === gridsData[i].x"
          :hoverGridY="hoverGrid.y === gridsData[i].y"
          :mousedownGrid="
            mousedownGrid.x === gridsData[i].x && mousedownGrid.y === gridsData[i].y
          "
          :dragMove="isMouseDragMove"
          :type="a.strong ? 'primary' : ''"
          v-for="(a, i) in data"
          :key="i"
          @mouseover="hoverGrid = gridsData[i]"
          @click="clickGrid(i)"
          @mouseout="hoverGrid = {}"
        >
          <span :title="a[label]">{{ a[label] }}</span
          ><i class="el-icon-close" @click="del(a)" />
          <div
            class="position-text"
            :title="`点击复制`"
            @click="$g.copy($g.stripHTML(getPositionText(gridsData[i])), true)"
            v-html="getPositionText(gridsData[i])"
          ></div>
          <div class="drag-select-btn" @mousedown.stop="clickResizeHandle"></div>
        </div>
      </div>
    </div>
 
    <!-- 拖拽 -->
    <sgDragMoveTile :data="dragMoveTileData" @scroll="scroll" />
  </div>
</template>
<script>
import sgDragMoveTile from "@/vue/components/admin/sgDragMoveTile";
export default {
  name: "sgExcelGrid",
  components: {
    sgDragMoveTile,
  },
  data() {
    return {
      A_Z: [...Array(26)].map((v, i) => String.fromCharCode(i + 65)),
 
      hoverGrid: {}, //移入的宫格标记
      mousedownGrid: {}, //点击的宫格标记
      gridsData: [], //记录网格宫格状态
      selectedGrids: [], //被选中的网格宫格DOM
      selectedDatas: [], //被选中的网格宫格数据
      rulerPosition: { x: 0, y: 0 },
      dragMoveTileData: {},
      gridWidth: 200,
      gridHeight: 100,
      colCount_: 8,
      pageSize_: 100,
      isMouseDragMove: false, //鼠标拖拽选中移动
      label: `label`, //显示文本字段名
    };
  },
  props: [
    "value",
    "props",
    "data",
    "pageSize", //每页显示多少个宫格
    "colCount", //列数
  ],
  computed: {},
  watch: {
    props: {
      handler(newValue, oldValue) {
        if (newValue && Object.keys(newValue).length) {
          newValue.label && (this.label = newValue.label);
        }
      },
      deep: true, //深度监听
      immediate: true, //立即执行
    },
    pageSize: {
      handler(newValue, oldValue) {
        newValue && (this.pageSize_ = newValue);
      },
      deep: true, //深度监听
      immediate: true, //立即执行
    },
    data: {
      handler(newValue, oldValue) {
        this.init_gridsData();
      },
      deep: true, //深度监听
      immediate: true, //立即执行
    },
    colCount: {
      handler(newValue, oldValue) {
        newValue && (this.colCount_ = newValue);
        this.$nextTick(() => {
          this.$el.style.setProperty("--gridWidth", `${this.gridWidth}px`); //js往css传递局部参数
          this.$el.style.setProperty("--gridHeight", `${this.gridHeight}px`); //js往css传递局部参数
          this.$el.style.setProperty(
            "--gridsWidth",
            `${this.colCount_ * this.gridWidth}px`
          ); //js往css传递局部参数
        });
      },
      deep: true, //深度监听
      immediate: true, //立即执行
    },
    selectedGrids: {
      handler(newValue, oldValue) {
        this.$emit(`selectedGrids`, newValue || []);
      },
      deep: true, //深度监听
      // immediate: true, //立即执行
    },
    selectedDatas: {
      handler(newValue, oldValue) {
        this.$emit(`selectedDatas`, newValue || []);
      },
      deep: true, //深度监听
      // immediate: true, //立即执行
    },
  },
  created() {},
  mounted() {
    this.init_grid_view();
    this.addEvents();
  },
  destroyed() {
    this.removeEvents();
  },
  methods: {
    clickGrid(i) {
      (this.mousedownGrid = this.gridsData[i]),
        (this.hoverGrid = {}),
        this.resetSelectGrid();
      this.selectedGrids = [this.gridsData[i]];
      this.selectedDatas = [this.data[i]];
    },
    clickResizeHandle(e) {
      this.originRect = e.target.parentNode.getBoundingClientRect();
      this.originRect.bottomRightX = this.originRect.x + this.originRect.width; //右下角坐标.x
      this.originRect.bottomRightY = this.originRect.y + this.originRect.height; //右下角坐标.y
      this.__addWindowEvents();
    },
    __addWindowEvents() {
      this.__removeWindowEvents();
      addEventListener("mousemove", this.mousemove_window);
      addEventListener("mouseup", this.mouseup_window);
    },
    __removeWindowEvents() {
      removeEventListener("mousemove", this.mousemove_window);
      removeEventListener("mouseup", this.mouseup_window);
    },
    mousemove_window(e) {
      this.isMouseDragMove = true;
      let { x, y } = e;
      let minWidth = 0,
        minHeight = 0,
        maxWidth = innerWidth,
        maxHeight = innerHeight;
      x < 0 && (x = 0),
        y < 0 && (y = 0),
        x > maxWidth && (x = maxWidth),
        y > maxHeight && (y = maxHeight);
      let style = {};
      style.x = this.originRect.x;
      style.y = this.originRect.y;
      style.width = x - this.originRect.x;
      style.width <= minWidth &&
        ((style.width = Math.abs(style.width)),
        ((style.x = this.originRect.x - style.width),
        (style.width = style.width + this.originRect.width)));
      style.height = y - this.originRect.y;
      style.height <= minHeight &&
        ((style.height = Math.abs(style.height)),
        ((style.y = this.originRect.y - style.height),
        (style.height = style.height + this.originRect.height)));
      style.width > maxWidth && (style.width = maxWidth);
      style.height > maxHeight && (style.height = maxHeight);
      this.calcRectGrid(style);
    },
    mouseup_window(e) {
      this.isMouseDragMove = false;
      this.__removeWindowEvents();
    },
    resetAllGridStatus() {
      this.resetSelectGrid();
      this.mousedownGrid = {};
    },
    resetSelectGrid(d) {
      this.selectedGrids = [];
      this.selectedDatas = [];
      let grids = this.$refs.dragContainer.querySelectorAll(`.grid`);
      grids.forEach((v) => {
        v.removeAttribute("selected-left");
        v.removeAttribute("selected-top");
        v.removeAttribute("selected-right");
        v.removeAttribute("selected-bottom");
        v.removeAttribute("selected");
      });
    },
    // 计算是否选中格子
    calcRectGrid(rect) {
      this.resetSelectGrid();
      this.selectedGrids = this.getSelectedDoms({
        targetDoms: this.$refs.dragContainer.querySelectorAll(`.grid`),
        rect,
      });
      this.selectedGrids.forEach((grid) => {
        let grid_rect = grid.getBoundingClientRect();
        let gridRectScreenWidth = grid_rect.x + grid_rect.width;
        let gridRectScreenHeight = grid_rect.y + grid_rect.height;
        grid_rect.x <= rect.x &&
          rect.x < gridRectScreenWidth &&
          grid.setAttribute("selected-left", true);
        grid_rect.y <= rect.y &&
          rect.y < gridRectScreenHeight &&
          grid.setAttribute("selected-top", true);
        let rectScreenWidth = rect.x + rect.width;
        let rectScreenHeight = rect.y + rect.height;
        grid_rect.x < rectScreenWidth &&
          rectScreenWidth <= grid_rect.x + grid_rect.width &&
          grid.setAttribute("selected-right", true);
        grid_rect.y < rectScreenHeight &&
          rectScreenHeight <= grid_rect.y + grid_rect.height &&
          grid.setAttribute("selected-bottom", true);
        grid.setAttribute("selected", true);
      });
    },
    // 获取被选中的DOM
    getSelectedDoms({ targetDoms, rect } = {}) {
      this.selectedDatas = [];
      return [...targetDoms].filter((targetDom, i) => {
        if (this.$g.isCrash(targetDom, rect)) {
          this.selectedDatas.push(this.data[i]);
          return targetDom;
        }
      }); // 获取被圈选的内容
    },
    // ----------------------------------------
    del(d) {
      this.$emit(`del`, d);
    },
    addEvents(d) {
      this.removeEvents();
      this.__removeWindowEvents();
      addEventListener("resize", this.resize);
    },
    removeEvents(d) {
      removeEventListener("resize", this.resize);
    },
    getPositionText(gridData) {
      return `<span>第${gridData.y + 1}行</span>&nbsp;<span>第${gridData.x}列</span>`;
    },
    init_grid_view() {
      this.resize();
      this.$nextTick(() => {
        this.init_sgDragMoveTile();
      });
    },
    init_gridsData(d) {
      this.gridsData = [...Array(this.pageSize_)].map((v, i) => ({
        x: this.A_Z[i % this.colCount_],
        y: Math.floor(i / this.colCount_),
      }));
      this.$nextTick(() => {
        this.resetAllGridStatus();
      });
    },
    init_sgDragMoveTile() {
      this.dragMoveTileData = {
        scrollContainer: this.$refs.scrollContainer,
        dragContainer: this.$refs.dragContainer,
      };
    },
    resize(d) {
      let scrollContainer = this.$refs.scrollContainer;
      scrollContainer && this.scroll({ target: scrollContainer });
    },
    scroll(e) {
      this.rulerPosition = {
        x: e.target.scrollLeft,
        y: e.target.scrollTop,
      };
    },
  },
};
</script>
<style lang="scss" scoped>
.sgExcelGrid {
  /*禁止选中文本*/
  user-select: none;
 
  overflow: hidden;
 
  $tickDis: 40px;
  $gridWidth: var(--gridWidth);
  $gridHeight: var(--gridHeight);
  $gridsWidth: var(--gridsWidth);
  $scrollbarWidth: 14px;
  width: 100%;
  height: 100%;
  position: relative;
  .ruler-corner {
    position: absolute;
    z-index: 2;
    left: 0;
    top: 0;
    width: $tickDis;
    height: $tickDis;
    box-sizing: border-box;
    border: 1px solid #ebeef5;
    border-right: none;
    border-bottom: none;
    background-color: #eff2f755;
    /*遮罩模糊*/
    backdrop-filter: blur(5px);
  }
  .horizontal-ruler {
    position: absolute;
    z-index: 1;
    left: 0;
    top: 0;
    margin-left: $tickDis;
    display: flex;
    flex-wrap: nowrap;
    border-top: 1px solid #ebeef5;
    border-left: 1px solid #ebeef5;
    /*遮罩模糊*/
    backdrop-filter: blur(5px);
    // box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
    .tick {
      display: flex;
      justify-content: center;
      align-items: center;
      flex-shrink: 0;
      width: $gridWidth;
      height: $tickDis;
      box-sizing: border-box;
      border-top: 1px solid transparent;
      border-left: 1px solid transparent;
      border-bottom: 1px solid #ebeef5;
      border-right: 1px solid #ebeef5;
      font-family: DIN-Black;
      background-color: #eff2f755;
      &[hoverGrid] {
        border-left: 1px solid #409eff;
        border-right: 1px solid #409eff;
        background-color: #b3d8ff99;
        color: #409eff;
      }
    }
  }
  .vertical-ruler {
    position: absolute;
    z-index: 1;
    left: 0;
    top: 0;
    margin-top: $tickDis;
    display: flex;
    flex-wrap: wrap;
    flex-direction: column;
    border-top: 1px solid #ebeef5;
    border-left: 1px solid #ebeef5;
    /*遮罩模糊*/
    backdrop-filter: blur(5px);
    // box-shadow: 2px 0 12px 0 rgba(0, 0, 0, 0.1);
    .tick {
      display: flex;
      justify-content: center;
      align-items: center;
      flex-shrink: 0;
      width: $tickDis;
      height: $gridHeight;
      box-sizing: border-box;
      border-top: 1px solid transparent;
      border-left: 1px solid transparent;
      border-bottom: 1px solid #ebeef5;
      border-right: 1px solid #ebeef5;
      font-family: DIN-Black;
      background-color: #eff2f7;
      background-color: #eff2f755;
      &[hoverGrid] {
        border-top: 1px solid #409eff;
        border-bottom: 1px solid #409eff;
        background-color: #b3d8ff99;
        color: #409eff;
      }
    }
  }
  .grids-scroll {
    width: calc(100% - #{$tickDis});
    height: calc(100vh - 310px);
    box-sizing: border-box;
    overflow: auto;
    position: relative;
    margin: $tickDis 0 0 $tickDis;
    .grids {
      width: calc(#{$gridsWidth} + #{$scrollbarWidth});
      min-height: calc(#{$gridHeight} + #{$scrollbarWidth});
      overflow: auto;
      display: flex;
      flex-wrap: wrap;
      align-content: flex-start;
      box-sizing: border-box;
      border-top: 1px solid #ebeef5;
      border-left: 1px solid #ebeef5;
 
      .grid {
        display: flex;
        justify-content: center;
        align-items: center;
        width: $gridWidth;
        height: $gridHeight;
        padding: 20px;
        box-sizing: border-box;
        border-top: 1px solid transparent;
        border-left: 1px solid transparent;
        border-bottom: 1px solid #ebeef5;
        border-right: 1px solid #ebeef5;
        word-wrap: break-word;
        word-break: break-all;
        white-space: break-spaces;
        position: relative;
 
        span {
          /*多行省略号*/
          overflow: hidden;
          word-break: break-all;
          white-space: break-spaces;
          display: -webkit-box;
          -webkit-box-orient: vertical;
          max-height: min-content;
          -webkit-line-clamp: 3;
          line-height: 1.2;
        }
        // 坐标文本
        .position-text {
          position: absolute;
          height: 22px;
          z-index: 1;
          left: 0px;
          top: 0px;
          display: none;
          flex-wrap: nowrap;
          white-space: nowrap;
          align-items: center;
          color: white;
          background-color: #00000055;
          box-sizing: border-box;
          padding: 0 5px;
          border-radius: 0 0 8px 0;
          >>> span {
            font-size: 12px !important;
          }
          cursor: cell;
          &:hover {
            background-color: #409eff;
            color: white;
          }
        }
        // 删除
        i.el-icon-close {
          z-index: 1;
          display: none;
          position: absolute;
          right: 0;
          top: 0;
          font-size: 12px !important;
          justify-content: center;
          align-items: center;
          color: white;
          background-color: #409eff;
          box-sizing: border-box;
          padding: 5px;
          border-radius: 0 0 0 8px;
          cursor: pointer;
          &:hover {
            background-color: #f56c6c;
          }
        }
        // 拖拽选区
        .drag-select-btn {
          position: absolute;
          height: 9px;
          width: 9px;
          z-index: 1;
          right: -4.5px;
          bottom: -4.5px;
 
          display: none;
          box-sizing: border-box;
          border: 2px solid white;
          background-color: #f56c6c;
          cursor: crosshair;
        }
 
        &:nth-of-type(2n) {
          background-color: #eff2f755;
        }
 
        &[hoverGridX] {
          border-left: 1px solid #409eff;
          border-right: 1px solid #409eff;
          background-color: #f2f8fe;
        }
        &[hoverGridY] {
          border-top: 1px solid #409eff;
          border-bottom: 1px solid #409eff;
          background-color: #f2f8fe;
        }
        &[mousedownGrid] {
          z-index: 2; //让drag-select-btn在顶端
          border: 1px solid #f56c6c;
          background-color: #f56c6c22;
          .position-text {
            background-color: #f56c6c66;
            color: white;
            &:hover {
              background-color: #f56c6c;
            }
          }
          i.el-icon-close {
            background-color: #f56c6c66;
            &:hover {
              background-color: #f56c6c;
            }
          }
          .drag-select-btn {
            display: block;
          }
          &:hover:not([dragMove]) {
            background-color: #f56c6c66;
            i,
            .position-text {
              display: flex;
            }
          }
        }
        &[selected] {
          z-index: 2; //让drag-select-btn在顶端
          border-top: 1px solid transparent;
          border-left: 1px solid transparent;
          border-right: 1px solid #f56c6c22;
          border-bottom: 1px solid #f56c6c22;
          background-color: #f56c6c22;
          .position-text {
            background-color: #f56c6c66;
            color: white;
            &:hover {
              background-color: #f56c6c;
            }
          }
          i.el-icon-close {
            background-color: #f56c6c66;
            &:hover {
              background-color: #f56c6c;
            }
          }
          .drag-select-btn {
            display: none;
          }
          &:hover:not([dragMove]) {
            border: 1px solid #f56c6c;
            background-color: #f56c6c66 !important;
          }
        }
        &[selected-left] {
          border-left: 1px solid #f56c6c;
        }
        &[selected-top] {
          border-top: 1px solid #f56c6c;
        }
        &[selected-right] {
          border-right: 1px solid #f56c6c;
        }
        &[selected-bottom] {
          border-bottom: 1px solid #f56c6c;
        }
        &[selected-right][selected-bottom] {
          .drag-select-btn {
            display: block;
          }
        }
        &[mousedownGridX] {
          border-left: 1px solid #f56c6c;
          border-right: 1px solid #f56c6c;
          background-color: #f56c6c22;
        }
        &[mousedownGridY] {
          border-top: 1px solid #f56c6c;
          border-bottom: 1px solid #f56c6c;
          background-color: #f56c6c22;
        }
        &[dragMove] {
        }
        &:hover:not([mousedownGrid]):not([dragMove]) {
          background-color: #b3d8ff99;
          i,
          .position-text {
            display: flex;
          }
        }
      }
      &[selectedGrids] {
        .grid {
          &:hover:not([mousedownGrid]):not([dragMove]):not([selected]) {
            border: 1px solid #409eff;
          }
        }
      }
    }
  }
}
</style>

应用

<template>
  <sgExcelGrid
    :props="{ label: `MC` }"
    :data="gridDatas"
    :pageSize="pageSize"
    @del="delGrid"
    @selectedDatas="selectedDatas"
  />
</template>
<script>
import sgExcelGrid from "@/vue/components/admin/sgExcelGrid";
export default {
  components: {
    sgExcelGrid,
  },
  data() {
    return {
      gridDatas: [
        { ID: 1, value: 1, MC: "显示文本1" },
        { ID: 2, value: 2, MC: "显示文本2" },
        { ID: 3, value: 3, MC: "显示文本3" },
        { ID: 4, value: 4, MC: "显示文本4" },
        { ID: 5, value: 5, MC: "显示文本5" },
      ],
      pageSize: 100, //每页显示多少个单元格
      rectSelectIDS: [], //选中的ID数组
    };
  },
  props: ["value"],
  computed: {},
  watch: {},
  created() {},
  mounted() {},
  destroyed() {},
  methods: {
    selectedDatas(d) {
      this.rectSelectIDS = d.map((v) => v.ID); //获取选中项ID数组
    },
    delGrid(d) {
      //删除单元格
    },
  },
};
</script>

基于

image.png

相关文章
|
2月前
|
JavaScript 前端开发 数据可视化
20.6K star!Excel级交互体验!这款开源Web表格神器绝了!
Handsontable 是一款功能强大的 JavaScript 数据表格组件,提供类 Excel 的交互体验。支持实时协作、数据绑定、公式计算等企业级功能,可轻松集成到 React/Vue/Angular 等主流框架。
164 11
|
6月前
|
Java API Apache
Java编程如何读取Word文档里的Excel表格,并在保存文本内容时保留表格的样式?
【10月更文挑战第29天】Java编程如何读取Word文档里的Excel表格,并在保存文本内容时保留表格的样式?
424 5
|
5月前
|
Python
使用OpenPyXL库实现Excel单元格其他对齐方式设置
本文介绍了如何使用Python的`openpyxl`库设置Excel单元格中的文本对齐方式,包括文本旋转、换行、自动调整大小和缩进等,通过具体示例代码展示了每种对齐方式的应用方法,适合需要频繁操作Excel文件的用户学习参考。
259 85
使用OpenPyXL库实现Excel单元格其他对齐方式设置
|
2月前
|
人工智能 数据可视化 前端开发
Probly:开源 AI Excel表格工具,交互式生成数据分析结果与可视化图表
Probly 是一款结合电子表格功能与 Python 数据分析能力的 AI 工具,支持在浏览器中运行 Python 代码,提供交互式电子表格、数据可视化和智能分析建议,适合需要强大数据分析功能又希望操作简便的用户。
376 2
|
3月前
|
文字识别 Serverless 开发工具
【全自动改PDF名】批量OCR识别提取PDF自定义指定区域内容保存到 Excel 以及根据PDF文件内容的标题来批量重命名
学校和教育机构常需处理成绩单、报名表等PDF文件。通过OCR技术,可自动提取学生信息并录入Excel,便于统计分析和存档管理。本文介绍使用阿里云服务实现批量OCR识别、内容提取、重命名及导出表格的完整步骤,包括开通相关服务、编写代码、部署函数计算和设置自动化触发器等。提供Python示例代码和详细操作指南,帮助用户高效处理PDF文件。 链接: - 百度网盘:[链接](https://pan.baidu.com/s/1mWsg7mDZq2pZ8xdKzdn5Hg?pwd=8866) - 腾讯网盘:[链接](https://share.weiyun.com/a77jklXK)
263 5
|
3月前
|
文字识别 BI
【图片型PDF】批量识别扫描件PDF指定区域局部位置内容,将识别内容导出Excel表格或批量改名文件,基于阿里云OCR对图片型PDF识别改名案例实现
在医疗和政务等领域,图片型PDF文件(如病历、报告、公文扫描件)的处理需求广泛。通过OCR技术识别这些文件中的文字信息,提取关键内容并保存为表格,极大提高了信息管理和利用效率。本文介绍一款工具——咕嘎批量OCR系统,帮助用户快速处理图片型PDF文件,支持区域识别、内容提取、导出表格及批量改名等功能。下载工具后,按步骤选择处理模式、进行区域采样、批量处理文件,几分钟内即可高效完成数百个文件的处理。
319 8
|
6月前
|
SQL 数据可视化 数据挖掘
想让Excel表格设计更美观?试试这几款好用工具!
Excel表格设计在项目管理和数据分析中至关重要。本文推荐四款辅助工具:板栗看板、Excel自动图表助手、Think-Cell Chart 和 Power BI,分别在任务管理、图表生成、数据可视化等方面表现突出,帮助你设计出更专业、美观的表格。
279 2
|
5月前
|
数据采集 数据可视化 数据挖掘
利用Python自动化处理Excel数据:从基础到进阶####
本文旨在为读者提供一个全面的指南,通过Python编程语言实现Excel数据的自动化处理。无论你是初学者还是有经验的开发者,本文都将帮助你掌握Pandas和openpyxl这两个强大的库,从而提升数据处理的效率和准确性。我们将从环境设置开始,逐步深入到数据读取、清洗、分析和可视化等各个环节,最终实现一个实际的自动化项目案例。 ####
684 10
|
7月前
|
数据采集 存储 JavaScript
自动化数据处理:使用Selenium与Excel打造的数据爬取管道
本文介绍了一种使用Selenium和Excel结合代理IP技术从WIPO品牌数据库(branddb.wipo.int)自动化爬取专利信息的方法。通过Selenium模拟用户操作,处理JavaScript动态加载页面,利用代理IP避免IP封禁,确保数据爬取稳定性和隐私性。爬取的数据将存储在Excel中,便于后续分析。此外,文章还详细介绍了Selenium的基本设置、代理IP配置及使用技巧,并探讨了未来可能采用的更多防反爬策略,以提升爬虫效率和稳定性。
422 4
|
3月前
|
分布式计算 Hadoop 大数据
从Excel到Hadoop:数据规模的进化之路
从Excel到Hadoop:数据规模的进化之路
66 10