Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/EmptyTag/146.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 Getting TypeError:selector.includes在使用cheerio和jsonframe进行刮取时不是函数_Javascript_Node.js_Cheerio_Jsonframe Cheerio - Fatal编程技术网

Javascript Getting TypeError:selector.includes在使用cheerio和jsonframe进行刮取时不是函数

Javascript Getting TypeError:selector.includes在使用cheerio和jsonframe进行刮取时不是函数,javascript,node.js,cheerio,jsonframe-cheerio,Javascript,Node.js,Cheerio,Jsonframe Cheerio,我正试图用以下代码废弃一个网站: const cheerio = require('cheerio'); const jsonframe = require('jsonframe-cheerio'); const $ = cheerio.load('https://coinmarketcap.com/all/views/all/'); jsonframe($); // initializes the plugin //exception handling process.on('uncau

我正试图用以下代码废弃一个网站:

const cheerio = require('cheerio');
const jsonframe = require('jsonframe-cheerio');

const $ = cheerio.load('https://coinmarketcap.com/all/views/all/');
jsonframe($); // initializes the plugin

//exception handling 
process.on('uncaughtException', err =>
  console.error('uncaught exception: ', err))
process.on('unhandledRejection', (reason, p) =>
  console.error('unhandled rejection: ', reason, p))

const frame = {
    "crypto": {         
        "selector": "tbody > tr",   
        "data": [{             
            "name": "td:nth-child(2) > a:nth-child(3)", 
            "url": {                                  
                "selector": "td:nth-child(2) > a:nth-child(3)",    
                "attr": "href"                     
            },
            "marketcap": "tr > td:nth-child(4)",
            "price": "tr > td:nth-child(5) > a:nth-child(1)", 
        }]
    }

};

let companiesList = $('tbody').scrape(frame);
console.log(companiesList); 
但是,在运行上述示例代码时,我会得到一个
未处理的PromisejectionWarning

(node:3890) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: selector.includes is not a function
有什么建议我做错了什么

谢谢你的回复

更新

我将代码更改为以下内容。但是,我只能废弃第一个元素

有什么建议可以解释为什么其他元素没有被废弃

const cheerio = require('cheerio')
const jsonframe = require('jsonframe-cheerio')
const got = require('got');


async function scrapCoinmarketCap() {
    const url = 'https://coinmarketcap.com/all/views/all/'
    const html = await got(url)
    const $ = cheerio.load(html.body)

    jsonframe($) // initializing the plugin

    let frame = {
        "Coin": "td.no-wrap.currency-name > a",
        "url": "td.no-wrap.currency-name > a @ href",
        "Symbol": "td.text-left.col-symbol",
        "Price": "td:nth-child(5) > a",
    }

    console.log($('body').scrape(frame, {
        string: true
    }))
}

scrapCoinmarketCap()

方法
cheerio.load()
不接受URL-它需要HTML作为字符串。

虽然我还没有研究cheerio的源代码,但模块似乎试图将URL解析为HTML文档,但显然失败了,各种错误开始出现

要解决此问题,您需要首先将该URL的HTML内容加载到一个变量中,然后将该HTML内容传递给cheerio

您可以使用诸如或之类的模块来实现这一点

下面是使用
get
加载页面的示例:

const got = require('got')
const cheerio = require('cheerio')

got('https://google.com')
.then(res => {
  const $ = cheerio.load(res.body)
  // Continue as usual
})
.catch(console.error)

根据更新的代码,您可以通过在每个
tr
上迭代来刮取所有货币数据:

$('body tr').each(function() {
  console.log($(this).scrape(frame, {
    string: true
  }))
})
然而,我认为最干净的方法(正如我在回答中所说的)是使用jsonframe-cheerio框架模式,它正是为了做到这一点:

let frame = {
  currency: {
    _s: "tr",  // the selector
    _d: [{  // allow you to get an array of data, not just the first item
      "Coin": "td.no-wrap.currency-name > a",
      "Url": "td.no-wrap.currency-name > a @ href",
      "Symbol": "td.text-left.col-symbol",
      "Price": "td:nth-child(5) > a"
    }]
  }
}

console.log($('body').scrape(frame, {
  string: true
}))

您使用的是哪个节点版本?您使用的是哪个版本的
jsonframe cheerio
?从代码片段中的语法判断,我怀疑您依赖于1.x版的文档或示例。最新版本2.x引入了很多变化。自述文件中有这样一条警告:“如果您一直在使用1.x.x版的jsonframe,请小心,有些内容会发生更改,以使其更灵活、使用更快(内联参数)并且在语法上更有意义。”@FelixKling我正在使用
节点--version
v8.4.0
@Boaz我正在使用
“cheerio”:“^1.0.0-rc.2”
“jsonframe cheerio”:^3.0.1“
谢谢您的回复!我很高兴地问您,您的最小可行示例是否可以显示我问题中示例链接的废弃。我很确定您可以将原始的废弃代码复制/粘贴到
//继续正常操作
-注释块中。你使用的cheerio不正确-只要用正确的方法尝试一下,我相信你会发现剩下的问题!我尝试了你的代码,但仍然得到与上面显示的相同的错误!刚刚修复了上面的代码。但是,
cheerio
只会刮取第一个元素。为什么会这样?谢谢你的回复!还有一个问题,如果我想从提取的URL中删除子页面,您会推荐什么?我是否需要通过
for循环运行此操作
,或者在
jsonframe
插件中是否有更好的方法?不确定,但我认为没有现成的选项可以这样做。您可能需要构建自己的递归函数。