我如何使用 axios 和 jsdom 从 cgv 网站获取 href 和 img
How I get contain of a href and img from cgv website using axios and jsdom
当我想定位并从该网站获取包含 href 和 img 时遇到问题 https://www.cgv.id/en/movies/now_playing 但我总是错误地获取它。这是可能的代码:
const { default: axios } = require("axios");
const { JSDOM } = require("jsdom");
(async () => {
try {
const { data } = await axios.get(
"https://www.cgv.id/en/movies/now_playing"
);
let dom = new JSDOM(data).window.document;
let list = [...dom.getElementsByClassName('movie-list-body').querySelectorAll('li')]
list = list.map(v => v.document.querySelectorAll('li a[href]').textContent.trimEnd())
console.log(list);
} catch (error) {
console.log(error);
}
})()
我的代码有误。我如何修复它并可以定位到包含 href 和 img 它?
在那里使用 JSDOM
有几个问题,尤其是您使用它的方式。
首先,当您使用 Axios
[=19= 检索时,相关网站没有任何带有 class 名称 movie-list-body
的 DOM 元素标记]
经过进一步检查,我意识到他们正在使用 jQuery
AJAX 调用从 JSON
文件中检索所有链接和图像。
以下是他们用来执行此操作的脚本。
<script>
$(function() {
$.ajax({
type: 'GET',
url: '/en/loader/home_movie_list',
success: function(data) {
$('.movie-list-body').html(data.now_playing);
$('.comingsoon-movie-list-body').html(data.comingsoon);
$('.lazy').lazy({
combined: true
});
}
});
});
</script>
在我看来,您应该只使用那个 JSON 文件。但是,如果您仍然想使用 JSDOM 以下是一些方法。
由于站点需要资源处理,如果要使用JSDOM解析整个页面,则必须传递JS中提到的选项DOM documentation如下:
const options = {
contentType: "text/html",
includeNodeLocations: true,
resources: "usable",
};
let dom = new JSDOM( data, options ).window.document;
这些选项将允许 JSDOM 加载所有资源,包括 jQuery,这将反过来允许节点进行 AJAX 调用,填充元素,然后理论上你可以提取链接。但是,有一些 CSS 文件是 JSDOM 无法解析的。
因此,我认为您最好的选择是按照以下几行做一些事情:
const { default: axios } = require("axios");
const { JSDOM } = require("jsdom");
(async () => {
try {
const data = await axios.get(
"https://www.cgv.id/en/loader/home_movie_list"
);
const base_url = 'https://www.cgv.id';
var dom = new JSDOM(data.data.now_playing).window.document;
var lists = [ ... dom.getElementsByTagName('ul')[0].children ]
var list = lists.map( list => [ base_url+list.firstChild.href, list.firstChild.firstChild.dataset.src ] );
console.log( list );
} catch (error) {
console.log(error);
}
})()
注意:
上述方法只有一个问题,即如果网站作者更改 JSON 文件的端点,您的解决方案将停止工作。
当我想定位并从该网站获取包含 href 和 img 时遇到问题 https://www.cgv.id/en/movies/now_playing 但我总是错误地获取它。这是可能的代码:
const { default: axios } = require("axios");
const { JSDOM } = require("jsdom");
(async () => {
try {
const { data } = await axios.get(
"https://www.cgv.id/en/movies/now_playing"
);
let dom = new JSDOM(data).window.document;
let list = [...dom.getElementsByClassName('movie-list-body').querySelectorAll('li')]
list = list.map(v => v.document.querySelectorAll('li a[href]').textContent.trimEnd())
console.log(list);
} catch (error) {
console.log(error);
}
})()
我的代码有误。我如何修复它并可以定位到包含 href 和 img 它?
在那里使用 JSDOM
有几个问题,尤其是您使用它的方式。
首先,当您使用 Axios
[=19= 检索时,相关网站没有任何带有 class 名称 movie-list-body
的 DOM 元素标记]
经过进一步检查,我意识到他们正在使用 jQuery
AJAX 调用从 JSON
文件中检索所有链接和图像。
以下是他们用来执行此操作的脚本。
<script>
$(function() {
$.ajax({
type: 'GET',
url: '/en/loader/home_movie_list',
success: function(data) {
$('.movie-list-body').html(data.now_playing);
$('.comingsoon-movie-list-body').html(data.comingsoon);
$('.lazy').lazy({
combined: true
});
}
});
});
</script>
在我看来,您应该只使用那个 JSON 文件。但是,如果您仍然想使用 JSDOM 以下是一些方法。
由于站点需要资源处理,如果要使用JSDOM解析整个页面,则必须传递JS中提到的选项DOM documentation如下:
const options = {
contentType: "text/html",
includeNodeLocations: true,
resources: "usable",
};
let dom = new JSDOM( data, options ).window.document;
这些选项将允许 JSDOM 加载所有资源,包括 jQuery,这将反过来允许节点进行 AJAX 调用,填充元素,然后理论上你可以提取链接。但是,有一些 CSS 文件是 JSDOM 无法解析的。
因此,我认为您最好的选择是按照以下几行做一些事情:
const { default: axios } = require("axios");
const { JSDOM } = require("jsdom");
(async () => {
try {
const data = await axios.get(
"https://www.cgv.id/en/loader/home_movie_list"
);
const base_url = 'https://www.cgv.id';
var dom = new JSDOM(data.data.now_playing).window.document;
var lists = [ ... dom.getElementsByTagName('ul')[0].children ]
var list = lists.map( list => [ base_url+list.firstChild.href, list.firstChild.firstChild.dataset.src ] );
console.log( list );
} catch (error) {
console.log(error);
}
})()
注意: 上述方法只有一个问题,即如果网站作者更改 JSON 文件的端点,您的解决方案将停止工作。