Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/457.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 从NodeJS中的HTML字符串获取所有文本内容_Javascript_Html_Node.js_Parsing - Fatal编程技术网

Javascript 从NodeJS中的HTML字符串获取所有文本内容

Javascript 从NodeJS中的HTML字符串获取所有文本内容,javascript,html,node.js,parsing,Javascript,Html,Node.js,Parsing,我只需要从带有空格或换行符的HTML字符串中获取文本内容,分隔不同元素的文本内容 例如,HTML字符串可能是: 首先 第二 我想要的是: 第一秒 或 首先 第二 我试图通过首先将整个字符串包装在div中,然后使用第三方库获取textContent来获取文本内容。但是,不同元素的文本内容之间没有我特别需要的间距或换行符(即,我得到的FirstSecond,这不是我想要的) 我现在考虑的唯一解决方案是创建一个DOM树,然后应用递归来获取包含文本的节点,然后将该元素的文本附加到带有空格的字符

我只需要从带有空格或换行符的HTML字符串中获取文本内容,分隔不同元素的文本内容

例如,HTML字符串可能是:

  • 首先
  • 第二
我想要的是:

第一秒

首先
第二
我试图通过首先将整个字符串包装在
div
中,然后使用第三方库获取
textContent
来获取文本内容。但是,不同元素的文本内容之间没有我特别需要的间距或换行符(即,我得到的
FirstSecond
,这不是我想要的)

我现在考虑的唯一解决方案是创建一个DOM树,然后应用递归来获取包含文本的节点,然后将该元素的文本附加到带有空格的字符串中。
有没有比这更干净、更整洁、更简单的解决方案?

您可以尝试使用regex去除html标记,对于您的示例,请尝试以下方法:

let str = `<ul>
<li>First</li>
<li>Second</li>
</ul>`

console.log(str)

let regex = '<\/?!?(li|ul)[^>]*>'

var re = new RegExp(regex, 'g');

str = str.replace(re, '');
console.log(str)
let str=`
  • 首先
  • 第二
` console.log(str) 让正则表达式=']*>' var re=新的RegExp(regex,'g'); str=str.replace(re.); console.log(str)
您可以尝试使用regex删除html标记,对于您的示例,请尝试以下操作:

let str = `<ul>
<li>First</li>
<li>Second</li>
</ul>`

console.log(str)

let regex = '<\/?!?(li|ul)[^>]*>'

var re = new RegExp(regex, 'g');

str = str.replace(re, '');
console.log(str)
let str=`
  • 首先
  • 第二
` console.log(str) 让正则表达式=']*>' var re=新的RegExp(regex,'g'); str=str.replace(re.); console.log(str)
使用DOM,您可以使用
document.Node.textContent
。但是,NodeJs没有textContent(因为它没有对DOM的本机访问),因此应该使用外部包。您可以使用npm安装
request
cheerio
cheerio
,由建议,可能是最容易使用的web抓取工具(也有像
jsdom
这样的复杂工具) 有了
cheerio
request
的力量,你就可以写了

const request = require("request");
const cheerio = require("cheerio");
const fs = require("fs");

//taken from https://stackoverflow.com/a/19709846/10713877
function is_absolute(url)
{
    var r = new RegExp('^(?:[a-z]+:)?//', 'i');
    return r.test(url);
}

function is_local(url)
{
    var r = new RegExp('^(?:file:)?//', 'i');
    return (r.test(url) || !is_absolute(url));
}

function send_request(URL)
    {
        if(is_local(URL))
        {
            if(URL.slice(0,7)==="file://")
                url_tmp = URL.slice(7,URL.length);
            else
                url_tmp = URL;

           //taken from https://stackoverflow.com/a/20665078/10713877
           const $ = cheerio.load(fs.readFileSync(url_tmp));
           //Do something
           console.log($.text())
        }
        else
        {
            var options = {
                url: URL,
                headers: {
                  'User-Agent': 'Your-User-Agent'
                }
              };

            request(options, function(error, response, html) {
                //no error
                if(!error && response.statusCode == 200)
                {
                    console.log("Success");

                    const $ = cheerio.load(html);


                    return Promise.resolve().then(()=> {
                        //Do something
                        console.log($.text())
                    });
                }
                else
                {
                    console.log(`Failure: ${error}`);
                }
            });
        }
    }
让我解释一下代码。您将URL传递给
发送请求
函数。它检查URL字符串是否是本地文件的路径(相对路径,或以
文件://
开头的路径)。如果是本地文件,则继续使用
cheerio
模块,否则,必须使用
request
模块向网站发送请求,然后使用
cheerio
模块。正则表达式用于
是绝对的
是局部的
。您可以使用
cheerio
提供的
text()
方法获取文本。在注释
//Do something
下,可以对文本执行任何操作。 有一些网站让您知道
“您的用户代理”
,将您的用户代理复制粘贴到该字段

下面几行就行了

//your local file
send_request("/absolute/path/to/your/local/index.html"); 
send_request("/relative/path/to/your/local/index.html"); 
send_request("file:///absolute/path/to/your/local/index.html"); 
//website
send_request("https://stackoverflow.com/"); 

编辑:我在linux系统上。

使用DOM,可以使用
document.Node.textContent
。但是,NodeJs没有textContent(因为它没有对DOM的本机访问),因此应该使用外部包。您可以使用npm安装
request
cheerio
cheerio
,由建议,可能是最容易使用的web抓取工具(也有像
jsdom
这样的复杂工具) 有了
cheerio
request
的力量,你就可以写了

const request = require("request");
const cheerio = require("cheerio");
const fs = require("fs");

//taken from https://stackoverflow.com/a/19709846/10713877
function is_absolute(url)
{
    var r = new RegExp('^(?:[a-z]+:)?//', 'i');
    return r.test(url);
}

function is_local(url)
{
    var r = new RegExp('^(?:file:)?//', 'i');
    return (r.test(url) || !is_absolute(url));
}

function send_request(URL)
    {
        if(is_local(URL))
        {
            if(URL.slice(0,7)==="file://")
                url_tmp = URL.slice(7,URL.length);
            else
                url_tmp = URL;

           //taken from https://stackoverflow.com/a/20665078/10713877
           const $ = cheerio.load(fs.readFileSync(url_tmp));
           //Do something
           console.log($.text())
        }
        else
        {
            var options = {
                url: URL,
                headers: {
                  'User-Agent': 'Your-User-Agent'
                }
              };

            request(options, function(error, response, html) {
                //no error
                if(!error && response.statusCode == 200)
                {
                    console.log("Success");

                    const $ = cheerio.load(html);


                    return Promise.resolve().then(()=> {
                        //Do something
                        console.log($.text())
                    });
                }
                else
                {
                    console.log(`Failure: ${error}`);
                }
            });
        }
    }
让我解释一下代码。您将URL传递给
发送请求
函数。它检查URL字符串是否是本地文件的路径(相对路径,或以
文件://
开头的路径)。如果是本地文件,则继续使用
cheerio
模块,否则,必须使用
request
模块向网站发送请求,然后使用
cheerio
模块。正则表达式用于
是绝对的
是局部的
。您可以使用
cheerio
提供的
text()
方法获取文本。在注释
//Do something
下,可以对文本执行任何操作。 有一些网站让您知道
“您的用户代理”
,将您的用户代理复制粘贴到该字段

下面几行就行了

//your local file
send_request("/absolute/path/to/your/local/index.html"); 
send_request("/relative/path/to/your/local/index.html"); 
send_request("file:///absolute/path/to/your/local/index.html"); 
//website
send_request("https://stackoverflow.com/"); 

编辑:我在linux系统上。

好的,您可以试试这个例子,这可能会对您有所帮助

我使用了
JSDom
模块

constjsdom=require(“jsdom”);
const{JSDOM}=JSDOM;
constdom=newjsdom(`helloworld

`); console.log(dom.window.document.querySelector(“p”).textContent);
顺便说一句,我帮了我


这段代码可以帮助我想:)

好的,你可以试试这个例子,这可能会对你有所帮助

我使用了
JSDom
模块

constjsdom=require(“jsdom”);
const{JSDOM}=JSDOM;
constdom=newjsdom(`helloworld

`); console.log(dom.window.document.querySelector(“p”).textContent);
顺便说一句,我帮了我


这段代码可以帮助我思考:)

你可以使用这个包来做这些事情,它是为抓取/导航/选择HTML内容而构建的。你可以使用这个包来做这些事情,它是为抓取/导航/选择HTML内容而构建的。这很有帮助,但这里的内容远不止回答问题所需的内容。如果你想让这个答案更有用,我建议你把关于在节点中使用fs/request的所有内容剥离出来,然后回答如何将html字符串转换成节点的内部文本。这很有帮助,但这里的内容远不止回答这个问题所需的内容。如果您想让这个答案更有用,我建议您去掉关于在节点中使用fs/request的所有内容,并回答如何将html字符串转换为节点的内部文本。