Web 抓取某些网页无法完成

Web scraping certain web page cannot finish

所以我正在学习使用节点 8 进行网络抓取,然后是这个 npm install --save request-promise cheerio puppeteer

代码简单

const rp = require('request-promise');
const url = 'https://www.examples.com'; //good

rp(url).then( (html) => {
    console.log(html);
}).catch( (e) => {
    console.log(e);
});

现在如果 url 是 examples.com,我可以看到普通的 html 输出,太棒了。

Q1:如果yahoo.com,则输出二进制数据,例如 ��i��,a��g�Z.~�Ż��ڔ+�<ٵ�A�y�+�c�n1O>Vr�K�#,bc���8����|� ��U>��p4U>mś0��Z��Xg"6��lS��2B��+��Y��Ɣ����? ��* 这是为什么?

Q2:然后 nasdaq.com, const url = 'https://www.nasdaq.com/earnings/report/msft'; 上面的代码不会完成,似乎挂在那里。

请问这是为什么?

Q2我不是很清楚,但是我可以回答Q1。

Yahoo 似乎将您检测为机器人并阻止您抓取页面!站点用来检测机器人的最常用方法是通过 User-Agent header。当您使用 request-promise(内部使用 request 库)发出请求时,它根本不会设置此 header。这意味着网站可以推断您的请求来自程序(而不是网络浏览器),因为没有 User-Agent header。然后他们会像对待机器人一样对待您,并向您发送乱码或永远不会为您提供内容。

您可以通过 manually setting a User-Agent header 模拟浏览器来解决此问题。请注意,这似乎适用于雅虎,但可能不适用于所有网站。其他网站可能会使用更先进的技术来检测机器人程序。

const rp = require('request-promise');
const url = 'https://www.yahoo.com'; //good

const options = {
  url,
  headers: {
    'User-Agent': 'Mozilla/5.0 (Android 4.4; Mobile; rv:41.0) Gecko/41.0 Firefox/41.0'
  }
};

rp(options).then( (html) => {
    console.log(html);
}).catch( (e) => {
    console.log(e);
});

Q2可能和这个有关,但是上面的代码没有解决。纳斯达克可能 运行 更复杂的机器人检测,例如检查 various other headers.