【问题标题】:Node.js puppeteer - Fetching content from a complex txt fileNode.js puppeteer - 从复杂的 txt 文件中获取内容
【发布时间】:2018-08-28 03:52:39
【问题描述】:

如何在 puppeteer 中下载、访问和处理复杂的 txt 文件?

我可以像这样访问一个 xml 文件 (Node.js puppeteer - Downloading/Accessing a xml file and process the content):

await page.goto(myPage, {waitUntil: 'load'});   

const newPage = await page.evaluate(() => {

    var columns = document.getElementsByTagName("VALUEA");      

    var values = {"values":[]};

    for(let f in columns){
        values.values.push(columns[f].innerText);
    }

    return JSON.stringify(values);

});

console.log(JSON.parse(newPage))

这会返回我想要的值。但是,如果我想访问一个看起来像这样的 txt 文件......并且为了测试想要获取所有“VALUEA”,我会得到:

{"values":[null,null,null]}

这是我正在查看的 TXT 文件:

<XYZ-DOCUMENT>117.txt : 20180824
<XYZ-HEADER>117.hdr.sgml : 20180824
<VALUE00>20180824153107
VALUE01:        117
VALUE02:    ABC

COMPANY:

    COMPANY DATA:   
        VALUE03:            Some Company
        VALUE04:            777

    BUSINESS ADDRESS:   
        VALUE05:        Some street
        VALUE06:            Some city

</XYZ-HEADER>
<DOCUMENT>
<VALUE07>ABC
<SEQUENCE>1
<FILENAME>primary_doc.xml
<TEXT>
<XML>
<?xml version="1.0" encoding="UTF-8"?>
<Submission xmlns="http://www.xyz.it/abc/" xmlns:com="http://www.xyz.it/abc/common">
  <headerData>
    <VALUE08>ABC</VALUE08>
    <xxxInfo>
      <xxx>
        <credentials>
          <VALUE09>777</VALUE09>
          <VALUE10>XXXXXXXX</VALUE10>
        </credentials>
      </xxx>
      <VALUE11>06-30-2018</VALUE11>
    </xxxInfo>
  </headerData>
  <bodyData>
    <coverPage>
      <VALUE12>06-30-2018</VALUE12>
      <VALUE13>1</VALUE13>
      <amendmentInfo>
        <VALUE14>STRAWBERRIES</VALUE14>
      </amendmentInfo>
      <xxxManager>
        <VALUE15>Corp</VALUE15>
        <address>
          <VALUE16:street1>MOUNTAIN STREET</VALUE16:street1>
          <VALUE17:city>NEW YORK</VALUE17:city>
        </address>
      </xxxManager>
      <provideInfoForInstruction5>N</provideInfoForInstruction5>
    </coverPage>
  </bodyData>
</Submission>
</XML>
</TEXT>
</DOCUMENT>
<DOCUMENT>
<TYPE>INFORMATION TABLE
<SEQUENCE>2
<FILENAME>xml_xyz.xml
<TEXT>
<XML>
<?xml version="1.0" encoding="UTF-8"?>
<informationTable xmlns="http://www.xyz.it/abc/informationtable" xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance">
<infoTable>
<VALUEA>Company A</VALUEA>
<VALUEB>INC</VALUEB>
<shParent>
<VALUEC>123</VALUEC>
<VALUED>AB</VALUED>
</shParent>
</infoTable>
<infoTable>
<VALUEA>Company B</VALUEA>
<VALUEB>LTD</VALUEB>
<shParent>
<VALUEC>567</VALUEC>
<VALUED>ST</VALUED>
</shParent>
</infoTable>

...

</informationTable>
</XML>
</TEXT>
</DOCUMENT>
</XYZ-DOCUMENT>

最后我想得到所有的VALUE(主要是VALUEA、VALUEB、VALUEC、VALUEC)!该怎么做?

【问题讨论】:

    标签: node.js puppeteer


    【解决方案1】:

    您可以使用以下方案从VALUEAVALUEBVALUECVALUED获取文本内容:

    const example = await page.evaluate( () =>
    {
        const page = document.createElement( 'html' );
        const page_content = document.body.textContent;
    
        page.innerHTML = page_content;
    
        return {
            'VALUEA' : Array.from( page.getElementsByTagName( 'VALUEA' ), e => e.textContent ),
            'VALUEB' : Array.from( page.getElementsByTagName( 'VALUEB' ), e => e.textContent ),
            'VALUEC' : Array.from( page.getElementsByTagName( 'VALUEC' ), e => e.textContent ),
            'VALUED' : Array.from( page.getElementsByTagName( 'VALUED' ), e => e.textContent )
        };
    });
    
    console.log( example.VALUEA[0] ); // Company A
    console.log( example.VALUEA[1] ); // Company B
    
    console.log( example.VALUEB[0] ); // INC
    console.log( example.VALUEB[1] ); // LTD
    
    console.log( example.VALUEC[0] ); // 123
    console.log( example.VALUEC[1] ); // 567
    
    console.log( example.VALUED[0] ); // AB
    console.log( example.VALUED[1] ); // ST
    

    【讨论】:

      【解决方案2】:

      要在 txt 中读取 dom 元素 html/xml,一种可能的解决方案是创建一个虚拟 dom 节点,如下所示:

      var el = document.createElement( 'html' );
       el.innerHTML = "<tagelement>content</tagelement>";  
      
      var columns = el.getElementsByTagName("tagelement");
      

      所以在你的例子中:

      const puppeteer = require('puppeteer');
      

      (异步 () => { 常量浏览器 = 等待 puppeteer.launch({ 无头:假 }); 常量页面 = 等待 browser.newPage(); await page.goto('http://example.com/file.txt', {waitUntil: 'load'});

      const newPage = await page.evaluate(() => {
      
          var el = document.createElement( 'html' );
          el.innerHTML = document.getElementsByTagName("pre")[0].innerText;
      
          var allValues = el.querySelectorAll("VALUEA, VALUEB, VALUEC, VALUED");  
      
          var values = {};
      
          for(let i = 0; i<allValues.length; i++){
              if(!(allValues[i].nodeName in values)){
                  values[allValues[i].nodeName] = [];
              }
              values[allValues[i].nodeName].push(allValues[i].innerText);
      
               }
      
              values =  JSON.stringify(values);
      
              return values;
          });
      
       console.log(JSON.parse(newPage))
      

      })();

      【讨论】:

      • 如果我“返回列”和“console.log(newPage)”,我仍然会得到 {} 或未定义。小提琴以 html 格式显示结构 ...
      • @PhilippM 那么也许你指向了错误的文件。如果您使用常规浏览器打开 xml url 会发生什么? document.getElementsByTagName 的工作方式与 html 相同
      • 在这种情况下它不是一个 .xml 文件......现在它是一个 .txt 文件。我从 xml 转换为 txt 文件...
      • @PhilippM 好点,我找到了解决方案。我已经更新了答案。这可以使用您的 xml 读取 txt 文件。
      • 现在效果很好!您能否通过添加值 VALUEB、VALUEC 和 VALUED 来扩展您的示例?
      猜你喜欢
      • 2012-11-04
      • 1970-01-01
      • 2021-03-30
      • 2020-06-26
      • 2012-07-29
      • 1970-01-01
      • 2022-11-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多