我正在尝试使用Cheerio抓取某些网站,但是由于该应用程序是动态的,因此内容不存在于HTML中,而是位于我不确定如何访问的JS对象上(我尝试过使用窗口,文档等)。
我的代码:
let axios = require('axios') // HTTP client
let cheerio = require('cheerio') // HTML parsing package
const url = 'https://www.foo.com'
const getWebsiteContent = async (url) => {
try {
const response = await axios.get(url)
const $ = cheerio.load(response.data)
console.log(response.data)
} catch (error) {
console.error(error)
}
}
getWebsiteContent(url)
console.log的结果(我只是粘贴了我需要访问的部分):
<!DOCTYPE html>
<html lang='en' ng-app='Test'>
<head>
</head>
<body class='' data-allow-utf8='false'>
<h1>HEADER</h1>
<script>
var matchData = function () {
Live.load.main({
version: "1.2",
sports: [
{
title: 'matchone',
subtitle: 'foo'
},
{
title: 'matchtwo',
subtitle: 'aaa'
}
],
})
}
</script>
<!-- More stuff -->
</body>
</html>
我要访问的数据是sports
函数中包含的Live.load.main
方法中的matchData
数组。
我什至不确定Cheerio是否是正确的工具,因为我期望数据会以HTML形式存在,但显然是以某种方式加载的,即在触发GET请求时只能在JS对象中看到它。
答案 0 :(得分:1)
首先,使用$('script').text()
获取脚本标签的内容。如果页面上还有更多脚本标签,则可能需要调整选择器。然后使用正则表达式匹配要访问的数组:
const script = $('script').text();
const [, arrStr] = script.match(/sports:\s+(\[[\s\S]+\])/);
最后,使用eval
将字符串转换为数组:
const arr = eval(arrStr);
请参见demo。