带有身份验证cookie的Nodejs网页抓取

Nodejs webpage scraping with authentication cookie

最近我正尝试从网站(kicktipp) using Nodejs, the request module 和 cheerio 抓取信息。由于该网站需要身份验证才能查看其大部分网站,因此我尝试通过 post 请求登录并检查用户是否使用以下代码登录(我用虚拟数据替换了凭据,但我在实际脚本中使用了真实数据):

var request = require('request');
var jar = request.jar();
var request = request.defaults({
  jar: jar,
  followAllRedirects: true
});
var jar = request.jar();
var cheerio = require('cheerio');

request.post({
    url: 'http://www.kicktipp.de/info/profil/loginaction',
    headers: { 'content-type': 'application/x-www-form-urlencoded' },
    method: 'post',
    jar: jar,
    body: 'kennung=test@example.com&passwort=1234567890&_charset_=UTF-8&submitbutton=Anmelden'
}, function(err, res, body){
  if(err) {
    return console.error(err);
  };

  request.get({
    url: 'http://www.kicktipp.de/',
    method: 'get',
    jar: jar
  }, function(err, res, body) {
    if(err) {
      return console.error(err);
    };

    var $ = cheerio.load(body);
    var text = $('.dropdownbox > li > a').text();
    console.log(text);
    var error = $('#kicktipp-content > div.messagebox.errors > p').text();
    console.log(error);
    var cookies = jar.getCookies('http://www.kicktipp.de/');
    console.log(cookies);
  });
});

html-form 发送的参数(通过浏览器检查)如下所示:

kennung=test@example.com&passwort=1234567890&_charset_=UTF-8&submitbutton=Anmelden

使用该脚本,我的 cookie jar 看起来像这样:

[ Cookie="JSESSIONID=F650D7F5CD6AF4F6B0944B2190EE2D29.kt213; Path=/; hostOnly=true; aAge=1ms; cAge=179ms" ]

JSESSIONID 已成功保存,但服务器不会登录,因为 console.log(text) 打印 Login 但如果用户正确登录,它应该打印 Logout .

在使用浏览器检查登录请求后,我发现每次通过 set-cookie 在响应 header 中请求此域上的页面时,浏览器都会收到一个新的 cookie,如下所示:

Set-Cookie: login=bS5zcGxpZXRob2V2ZXJAZ21haWwuY29tOjE0NzU0MDA3MjAxMjA6Mzg1NTI4OGY3ODgzN2FkMzllNTA0NWNkY2ZjMjBjZGM; Domain=.kicktipp.de; Expires=Sun, 02-Oct-2016 09:32:00 GMT; Path=/; HttpOnly

但是我无法(或者只是不知道如何)将此 cookie 放入我的请求 jar 中,因此无法以登录用户身份访问该页面。

我是否缺少任何保持登录状态(或完全登录页面)的信息?提前致谢。

问题是此页面似乎需要您在第一次访问页面时获得的特定 cookie(在本例中它似乎是时区 cookie)。要获取此 cookie,您只需在向服务器发送登录 (POST) 请求之前访问该页面(使用 GET 请求)。 在这种情况下,就像在上面的代码周围包装另一个 GET 请求一样简单:

var loginLink = 'http://www.kicktipp.de/info/profil/login';

// creating a clean jar
var j = request.jar();

request.get({url: loginLink, jar: j}, function(err, httpResponse, html) {
  // place POST request and rest of the code here
});