使用node.js从div中检索文本

问题描述 投票:0回答:2

我目前正在尝试编写一个抓取工具,它将使用node.js从Facebook帖子内的div中获取所有“p”标签

页面上的每个帖子都位于具有此类的 div 中:.text_exposed_root

有时每个帖子中都有多个“p”标签,因此理想情况下,如果可能的话,我需要获取该 div 中的所有 html 文本。我正在使用 Cheerio 和请求模块,到目前为止我的代码如下:

request(BTTS, function(error, response, body){
    if (!error){
        var $ = cheerio.load(body), 
        post = $(".text_exposed_root p").text();

        console.log(post);
    } else {
        console.log("We’ve encountered an error: " + error);
    }
})

我尝试过使用 .text .value 和 .html 但它们都只返回空白响应。我猜我需要获取该 div 中的所有“p”标签并可能转换为字符串?

提前致谢。

编辑:

var url = ('https://www.facebook.com/BothTeamsToScore');

request({url:url, headers: headers}, function(error, response, body){
    if (!error){

        var strippedBody = body.replace(/<!--[\s\S]*?-->/g, "")

        console.log(strippedBody);

        var $ = cheerio.load(strippedBody), 
        post = $(".text_exposed_root p").text();

        console.log(post);
    } else {
        console.log("We’ve encountered an error: " + error);
    }
})
node.js request cheerio
2个回答
2
投票

首先,您需要为您的请求设置一些标头。如果没有它们,Facebook 将通过“不支持的浏览器”页面进行响应。这是你的第一个问题。

var headers = {
   'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36',
   'Content-Type' : 'application/x-www-form-urlencoded'
}

var url = BTTS

request({url:url, headers: headers}, function(error, response, body){
    if (!error){
        var $ = cheerio.load(body.replace(/<!--|-->/g, ''))
        console.log($('.text_exposed_root p').text())
    } else {
        console.log("We’ve encountered an error: " + error);
    }
})

另一件事应该注意的是,内容出现在 html 注释中。即

<code class="hidden_elem"><!-- 
... 
    <div class="text_exposed_root">
        <p>text</p>

Cheerio 不会解析注释节点,因此您很可能需要删除

<!--
-->
并将结果加载回 Cheerio 以解析您想要的 html 部分。祝你好运!


0
投票

有一个库 node-html-parser,您可以使用它来 parse 一个 html 字符串,然后用它来执行类似 DOM 的操作。

在您的情况下,您可以创建一个通过 .text_exposed_root 查询所有 div 的函数,然后提取 innerHtml

文件:html.utiliy.ts

import parse from "node-html-parser";

export class HTMLUtility {
    /**
     * Function that queries all HTML text by given class name 
     * @param text actual Html Text as string
     * @param className targetted class name
     * @returns a list with inner html text found inside class name
     */
    public static getAllParagraphsByDivClass(text: string, className: string): string[] {
        const root = parse(text);
        const htmlDivElement = root.querySelectorAll(`.${className}`);
        return htmlDivElement.map((m) => m.innerHTML);
    }
}

文件:html.utility.unit.test.ts

import { describe, it } from "mocha";
import { assert } from "chai";
import { HTMLUtility } from "../../../../src/application/helpers/html.utiliy";

describe("HTML Utility", () => {
    describe("get all elements inside div", () => {
        it("given certain html, will return a list of text inside each div.className", async () => {
            // arrange
            const post1 = "<p>Lorem ipsum dolor sit amet</p><p>consectetur adipiscing elit.</p>";
            const post2 = "<p>Aliquam iaculis ornare massa</p><p>ut porta enim mollis ac.</p>";
            const post3 = "<p>Maecenas sodales pretium sollicitudin.</p>";

            const htmlText = `
            <body>
                <div class='text_exposed_root'>${post1}</div>
                <div class='text_exposed_root'>${post2}</div>
                <div class='text_exposed_root'>${post3}</div>
            </body>`;

            // act
            const paragraphList = HTMLUtility.getAllParagraphsByDivClass(htmlText, "text_exposed_root");

            // assert
            assert.equal(paragraphList[0], post1);
            assert.equal(paragraphList[1], post2);
            assert.equal(paragraphList[2], post3);
        });
    });
});
© www.soinside.com 2019 - 2024. All rights reserved.