【问题标题】:Cheerio Not Parsing HTML CorrectlyCheerio 没有正确解析 HTML
【发布时间】:2019-06-19 03:48:35
【问题描述】:

我有一个行数组,我从 html 的表中解析出来,存储在一个列表中。列表中的每一行都是一个看起来像这样的字符串:

["<td headers="DOCUMENT" class="t14data"><a target="6690-Exhibit-C-20190611-1" href="http://www.fara.gov/docs/6690-Exhibit-C-20190611-1.pdf" class="doj-analytics-processed"><span style="color:blue">Click Here </span></a></td><td headers="REGISTRATIONNUMBER" class="t14data">6690</td><td headers="REGISTRANTNAME" class="t14data">SKDKnickerbocker LLC</td><td headers="DOCUMENTTYPE" class="t14data">Exhibit C</td><td headers="STAMPED/RECEIVEDDATE" class="t14data">06/11/2019</td>","<td headers="DOCUMENT" class="t14data"><a target="5334-Supplemental-Statement-20190611-30" href="http://www.fara.gov/docs/5334-Supplemental-Statement-20190611-30.pdf" class="doj-analytics-processed"><span style="color:blue">Click Here </span></a></td><td headers="REGISTRATIONNUMBER" class="t14data">5334</td><td headers="REGISTRANTNAME" class="t14data">Commonwealth of Dominica Maritime Registry, Inc.</td><td headers="DOCUMENTTYPE" class="t14data">Supplemental Statement</td><td headers="STAMPED/RECEIVEDDATE" class="t14data">06/11/2019</td>"]

使用 puppeteer 使用以下 page.evaluate 函数从页面中提取代码。

然后我想用cheerio 解析这段代码,我发现它更简单、更容易理解。但是,当我将每个 html 字符串传递给cheerio 时,它无法正确解析它们。这是我正在使用的当前函数:

    let data = res.map((tr) => {
        let $ = cheerio.load(tr);
        const link = $("a").attr("href");
        const number = $("td[headers='REGISTRATIONNUMBER']").text();
        const name = $("td[headers='REGISTRANTNAME']").text();
        const type = $("td[headers='DOCUMENTTYPE']").text();
        const date = $("td[headers='STAMPED/RECEIVEDDATE']").text();
        return { link, number, name, type, date };
    });

由于某种原因,只有“a”标签对每一行都正常工作。意思是,“链接”变量已正确定义,但其他变量均未正确定义。当我使用 $("*") 返回应该是所有 td 的列表时,它返回一个不寻常的节点列表:

我做错了什么,我如何才能访问带有各种标题及其文本内容的 td?谢谢!

【问题讨论】:

    标签: javascript dom web-scraping puppeteer cheerio


    【解决方案1】:

    通常看起来更像这样:

    let data = res.map((i, tr) => {
      const link   = $(tr).find("a").attr("href");
      const number = $(tr).find("td[headers='REGISTRATIONNUMBER']").text();
      const name   = $(tr).find("td[headers='REGISTRANTNAME']").text();
      const type   = $(tr).find("td[headers='DOCUMENTTYPE']").text();
      const date   = $(tr).find("td[headers='STAMPED/RECEIVEDDATE']").text();
      return { link, number, name, type, date };
    }).get();
    

    请记住,cheerio 地图的参数与 js 地图相反。

    【讨论】:

    • 感谢您的评论。我实际上并没有使用 Cheerio 的地图,我使用的是常规地图,并且我的论点没有颠倒。这里的 res 数组是一个简单的数组,带有一个字符串化的 html 数据列表。
    【解决方案2】:

    我找到了解决方案。我只是通过 puppeteer 返回完整的 html,而不是尝试获取单个行,然后使用上述建议(来自@pguardiario)来解析文本:

     const res = await page.evaluate(() => {
                return document.body.innerHTML;
            });
    
     let $ = cheerio.load(res);
            let trs = $(".t14Standard tbody tr.highlight-row");
    
     let data = trs.map((i, tr) => {
            const link = $(tr).find("a").attr("href");
            const number = $(tr).find("td[headers='REGISTRATIONNUMBER']").text();
            const registrant = $(tr).find("td[headers='REGISTRANTNAME']").text();
            const type = $(tr).find("td[headers='DOCUMENTTYPE']").text();
            const date = moment($(tr).find("td[headers='STAMPED/RECEIVEDDATE']").text()).valueOf().toString();
            return { link, number, registrant, type, date };
        });
    

    【讨论】:

      猜你喜欢
      • 2016-05-30
      • 1970-01-01
      • 2015-05-17
      • 1970-01-01
      • 2015-10-07
      • 2021-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多