javascript - Cheerio Node.JS 外部标题链接问题

标签 javascript jquery node.js web-scraping request

我正在构建一个示例测试抓取器来了解 Cheerio 和 jQuery。

在收到一组 URL 并存储它们后,我对第二个请求摸不着头脑,即执行另一个请求来加载这些 URL 并从该页面的标题中提取标题。

我的代码如下所示。

   var request = require('request'),
    cheerio = require('cheerio');
    urls = [];
    titles = [];
request('http://reddit.com', function(err, resp, body){
 if(!err && resp.statusCode == 200){
 var $ = cheerio.load(body);

   $('a.title', '#siteTable').each(function(){
   var url =  $(this).attr('href');
   urls.push(url);
});
   //issue is here
   for(var i = 0; i < urls.length; i++){
   request(urls[i], function(err, resp, body){
    var $ = cheerio.load(body);

    var title = $("title").text();

   console.log(title);
   });
   }
  }
});

当我从页面中获取标题时,似乎在某处得到了未定义的属性。

我必须提到我是 jQuery 新手,所以这段代码可能看起来很荒谬(我假设)。

我从控制台收到的错误是,

TypeError: Cannot read property 'parent' of undefined
    at Function.exports.update (/home/pi/node_modules/cheerio/lib/parse.js:55:25)
    at module.exports (/home/pi/node_modules/cheerio/lib/parse.js:17:11)
    at Function.exports.load (/home/pi/node_modules/cheerio/lib/static.js:19:14)
    at Request._callback (/home/pi/scraper.js:16:22)
    at self.callback (/home/pi/node_modules/request/request.js:187:22)
    at Request.emit (events.js:95:17)
    at Request.init (/home/pi/node_modules/request/request.js:275:17)
    at new Request (/home/pi/node_modules/request/request.js:129:8)
    at request (/home/pi/node_modules/request/index.js:55:10)
    at Request._callback (/home/pi/scraper.js:15:6)

我知道这个错误意味着我有一个 undefined variable ,并且我正在尝试创建像 .someThing 这样的辅助属性,但错误指向第二个请求中的回调函数。

关于如何解决这个问题有什么建议吗?

最佳答案

返回的 URL 之一如下所示

/r/Jokes/comments/4yp0ex/mom_dont_freak_out_but_im_in_the_hospital/

可能还有其他的,但是查看 reddit 可以清楚地看到 anchor 和 href

<a class="title may-blank " href="/r/Jokes/comments/4yp0ex/mom_dont_freak_out_but_im_in_the_hospital/" tabindex="1" rel="">"Mom? Don't freak out, but I'm in the hospital..."</a>

当然,尝试使用请求来获取没有协议(protocol)或域的 URL 会失败,并且一切都会崩溃。

您必须通过添加域并创建绝对 URL 来处理内部链接,一种简单的方法是这样的

for (var i = 0; i < urls.length; i++) {
  var uri = (/^(f|ht)tps?:\/\//i.test(urls[i]) ? "" : "https://www.reddit.com") + urls[i];

  request(uri, function(err, resp, body) {
    if (err) {
      // handle errors
    } else {
        var $ = cheerio.load(body);
        var title = $("title").text();

        console.log(title);
    }
  });
}

运行它,你会发现在几个 URL 之后,你会遇到“502 Bad gateway”,现在你必须处理这个问题,可能还有许多其他事情,因为不能保证 Reddit 上发布的所有蹩脚链接确实有效。

关于javascript - Cheerio Node.JS 外部标题链接问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39058524/

相关文章:

javascript - 在 JavaScript 类中调用嵌套函数

node.js - Puppeteer 无法在 Arch Linux 上运行 NodeJS 17

node.js - 在 Windows 上使用 npm 运行并发命令?

android - Cordova - ANDROID_HOME 未设置且 "android"命令不在您的 PATH 中。您必须至少满足以下条件之一

当脚本不是页面的一部分时,JavaScript "document is not defined"错误

javascript - react 和模糊事件

javascript - 如何复制手动(未)选中复选框的状态?

javascript - 如何处理下拉列表的小数值而不舍入或 trim 零

javascript - 基本 Jquery - 如果 TD 中存在文本,则使 DIV 可见

jquery - 删除字符串中的所有 HTML 标签(使用 jquery text() 函数)