【问题标题】:Axios url get reques to for html response is 200 but response.data is emptyAxios url 获取对 html 响应的请求为 200 但 response.data 为空
【发布时间】:2020-04-06 22:58:11
【问题描述】:

所以我使用这个 URL 是因为我想使用 axios 和 Cheerio 来抓取 html: https://www.mgewholesale.com/ecommerce/Bags%20and%20Cases.cfm?cat_id=876

我在邮递员中测试了一个获取请求,它在状态 200 下运行良好

使用此代码也适用于状态 200,但 response.data 为空

更新,所以使用这段代码,我得到了填充数据对象的实际响应,但是当我尝试访问 response.data 时,它向我显示了这个错误:

const axios = require('axios'); 
const cheerio = require('cheerio');
const https = require('https');

let fs = require('fs');

const httpsAgent = new https.Agent({ keepAlive: true });

axios
    .get('https://www.mgewholesale.com/ecommerce/Bags%20and%20Cases.cfm', {
        httpsAgent,
        params: {
            cat_id: '876',
        },
        headers: {
            'Accept-Encoding': 'gzip, deflate, br',
        },
        //is the same as set the entire url
    })
    .then((res) => {

        console.log(res.data)
        //this triggers the error

       // let status = res.status;
        console.log(status);
       //Status 200
       console.log(response)
        //This brings the entire response with data object filled

    });

ERROR:
(node:9068) UnhandledPromiseRejectionWarning: Error: read ECONNRESET
    at TLSWrap.onStreamRead (internal/stream_base_commons.js:205:27)
(node:9068) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:9068) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

我尝试使用整个 url 和带有参数的 url,它给我带来了空数据,但如果我尝试使用其他 url,例如:https://www.google.com,它给我带来了实际的 html。

【问题讨论】:

    标签: javascript node.js web-scraping axios cheerio


    【解决方案1】:

    问题是您的查询参数未正确添加。

    axios.get 的第二个参数中删除+ '.json'

    我很惊讶这本身并没有引发错误,但显然 axios 只是在播放并附加 0=[object+Object].json,将您的 URL 变成:https://www.mgewholesale.com/ecommerce/Bags%20and%20Cases.cfm?0=[object+Object].json

    我无法对其他答案添加评论,但这是不正确的,因为您在致电 .get() 后正确使用了承诺链 (.then)。


    编辑:
    对于这个特定的 URL,您似乎需要一些额外的标头,以及在初始响应后保持连接活动的能力:

    const axios = require('axios'); //15k (gzipped: 5.1k)
    const cheerio = require('cheerio');
    const https = require('https');
    
    let fs = require('fs');
    
    const httpsAgent = new https.Agent({ keepAlive: true });
    
    axios
        .get('https://www.mgewholesale.com/ecommerce/Bags%20and%20Cases.cfm', {
            httpsAgent,
            params: {
                cat_id: '876',
            },
            headers: {
                'Accept-Encoding': 'gzip, deflate, br',
            },
            //is the same as set the entire url
        })
        .then((res) => {
            let status = res.status;
            console.log(status);
            //This should now output the html content
            console.log(res.data);
        })
        .catch(err => console.error(err));
    

    编辑 2:
    在上面的代码中添加了处理错误的正确方法。

    编辑 3:
    确保您在.then() 块中登录的变量都已定义。此外,要获得更多有用的错误,请将.catch() 添加到末尾:

        .then((res) => {
            console.log(res.data);
            //this triggers the error
    
            let status = res.status;
            console.log(status);
            //Status 200
            console.log(res);
            //This brings the entire response with data object filled
        })
        .catch(err => console.error(err));
    

    【讨论】:

    • 我也尝试不使用 +'.json',我在其他帖子中看到了该解决方案,但它对我不起作用,我还尝试将整个 url 放在一起(包括参数)跨度>
    • 您的控制台中是否出现这样的 CORS 错误:Access to XMLHttpRequest at 'https://www.mgewholesale.com/ecommerce/Bags%20and%20Cases.cfm?cat_id=876' from origin 'https://cdpn.io' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. 编辑:忽略,因为我现在看到您正在从服务器端使用。尽管如此,最好检查您的请求标头是否有任何类型的跨源限制。
    • 不,正如我所说,在邮递员中工作正常,但在 axios 中,它的状态为 200,但 response.data 为空
    • 我已经用解决方案更新了我的答案。我能够在本地完成这项工作。
    • +1 表示网站需要的 accept-encoding: gzip 标头并且需要设置保持活动状态
    猜你喜欢
    • 1970-01-01
    • 2017-10-31
    • 2020-02-06
    • 2022-01-22
    • 2017-10-31
    • 2015-04-13
    • 2020-12-20
    • 2018-04-14
    • 2020-10-05
    相关资源
    最近更新 更多