首页 > 解决方案 > 抓取浏览器中呈现的文本

问题描述

我正在尝试使用 innerText 属性从 html 中提取文本,如下所示:console.log(document.getElementById('row').innerText)

但是,输出的方式与我在浏览器上看到的方式不同。

产生差异的原因是第一种情况下的表格元素包含 inline-block 的样式(见下文)。

如何解决它,以便获得与浏览器中显示的格式相同的文本?

情况#1: 输入:

<html>
   <body id='test'>
      <table style="display: inline-block">
         <tr>
            <td>1</td>
         </tr>
         <tr>
            <td>2</td>
         </tr>
      </table>
      <table style="display: inline-block">
         <tr>
            <td>3</td>
         </tr>
         <tr>
            <td>4</td>
         </tr>
      </table>
   </body>
</html>

预期输出:

1 3
2 4

实际输出

1
2
3
4

情况#2: 输入:

<html>
   <body id='test'>
      <table>
         <tr>
            <td>1</td>
         </tr>
         <tr>
            <td>2</td>
         </tr>
      </table>
      <table>
         <tr>
            <td>3</td>
         </tr>
         <tr>
            <td>4</td>
         </tr>
      </table>
   </body>
</html>

预期输出:

1 
2 
3
4

实际输出

1
2
3
4

标签: javascriptweb-scrapinginnertext

解决方案


虽然似乎应该有一种更简单的方法,但 DOM 不理解可见顺序,因此您可能必须手动转置值,例如:

    // Populates domOrder from DOM (Note: These example selectors are fragile)
    const domOrder = [], visibleOrder = [];
    // Uses spread operator to get an array of tables
    const inlineTables = [...document.querySelectorAll("table")]
      .filter(table => table.style.display == "inline-block")
        .forEach(table => {
          // Gets rows
          [...table.children]
            // I'm not certain whether splitting on newlines is always reliable
            .forEach(tr => domOrder.push(tr.innerText.split(/\n/g)));
        });
    // Populates visibleOrder by transposing values from domOrder
    const rowCount = domOrder.length;
    const colCount = domOrder[0].length;
    domOrder[0].forEach( (col, colNum) => { 
      // Adds a row to visibleOrder
      visibleOrder[colNum] = []; 
      // Transposes the values 
      domOrder.forEach( (row, rowNum) => {
        visibleOrder[colNum][rowNum] = domOrder[rowNum][colNum];
      });
    });
    console.log(visibleOrder);
    <table style="display: inline-block">
       <tr><td>1</td></tr>
       <tr><td>2</td></tr>
    </table>
    <table style="display: inline-block">
       <tr><td>3</td></tr>
       <tr><td>4</td></tr>
    </table>
    <table style="display: inline-block">
       <tr><td>5</td></tr>
       <tr><td>6</td></tr>
    </table>

这是一个更强大的矩阵转置示例。


推荐阅读