我如何使用 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 文件的端点,您的解决方案将停止工作。