puppeteerとrequestの間でcookiesを互いに転送する


リファレンス
  • QQ群-Javascript上級爬虫類-作者自建群、ようこそ!
  • awesome-java-crawler-著者らが収集した爬虫類関連ツールと資料
  • puppeteer中国語ドキュメント
  • request.jsライブラリ

  • 前言
    目的はpuppeteerでログインプロセスの自動化を実現し、ログイン後に取得した合法的なcookiesをnode端に伝送し、実際に大量にデータをキャプチャするにはrequestを使用し、キャプチャ性能と信頼性を高めることである.
    puppeteer -> request
  • まず、requestデフォルトパラメータにjar属性を追加する:
    const cookieJar = request.jar()
    const rp = request.defaults({
      jar: cookieJar,
      ... //   request    
    })
    このように、このrpオブジェクトを使用すると、このcookieJarオブジェクトを使用して応答から解析されたcookiesを格納するか、cookieJarオブジェクトを操作することによって単一のcookie
  • を削除変更することができる.
  • puppeteerによってブラウザからcookies
    const cookies = await page.cookies()
    を取得ここのcookiesは普通のjavascriptオブジェクトの配列で、各要素にはname、value、domain、path、expires、httpOnly、secureなどの属性
  • が含まれている.
  • ブラウザで取得したcookiesをcookieJarに埋め込むには、次の手順に重点を置きます.
  • cookieJarの各cookieは単純なjsオブジェクトではなくCookieオブジェクトである、cookieJar.setCookieは単純なjsオブジェクトを受け入れず、Cookieオブジェクトを作成するか、文字列を入力してこの方法を自分で解析するか、ここで最初のスキームを選択するので、依存
  • を導入する必要があります.
  • requestのクッキー処理はtough-cookieというライブラリに依存するため、このライブラリを明示的にインストールして導入する必要があります.最新版を使用しないでください.そうしないと、requestの依存バージョンと一致しません.package-lockからjsonでtough-cookieのバージョン番号を見つけ、npm install [email protected]で特定のバージョン
  • をインストールします.
  • また、tough-cookieのCookieオブジェクトはnameではなくkeyをcookie名として使用する点に注意する必要があります.CookieオブジェクトのexpiresプロパティはDateオブジェクトまたは「Infinity」文字列であり、puppeteer側のオブジェクトのexpiresはunixタイムスタンプであり、-1で永久を表す.そのため、
  • の変換が必要です.
    cookies.forEach(json => {
      const { name, domain } = json
      json.key = name
      json.expires = json.expires > 0 ? new Date(json.expires * 1000) : 'Infinity'
      const cookie = Cookie.fromJSON(json)
      cookieJar.setCookie(cookie, 'https://' + domain)
    })
  • cookiesの設定が完了するとnodejs側はログイン後の状態に相当する、ログイン後の権限内容
  • を正常に要求することができる.
    request -> puppeteer
  • では、nodejs側からブラウザ側に逆転送する必要がある場合があります.例えば、ブラウザを借りて複雑な操作のあるプロセスを完了するなど、前節の逆操作に関連します.
  • ここのトラブルはrequest包装後のクッキーの操作方法が全面的ではないことです.例えば、クッキーJarを使えないことに気づきました.getCookies()このメソッドは'.xxxx.com'のようなdomainの下のcookiesは、ソースコードを分析することによって、以下の方法を書いて、cookieJarのすべてのcookieオブジェクト
    async function allCookies (jar) {
      const store = jar._jar.store
      return (await Promise.all(Object.keys(store.idx).map(d => util.promisify(store.findCookies).call(store, d, null)))).flat()
    }
    を一度に取得するしかありません.
  • 以上'JAr'のような属性はtough-cookieの内部プライベート属性に属し、これは上述のコードが実際にhack方式であり、必ずしも他のバージョン
  • に適用されるとは限らないことを意味する.
  • util.promisifyはnodejs標準ライブラリにおけるメソッドであり、コールバック方式の関数をPromise方式
  • に変換するために使用される.
  • Array.flatメソッドはnode 11ならではですが、古いバージョンであれば、自分でメソッドを書いて配列
  • を展開してください.
  • それからCookieオブジェクトをpuppeteerが受け入れる普通のjsオブジェクトに簡単に変換することができます
    const cookies = await allCookies(cookieJar)
    cookies = cookies.map(c => ({ ...c, expires: c.expires instanceof Date ? c.expires.getTime() / 1000 : -1, name: c.key }))
    await page.setCookie.apply(page, cookies)
    Pageのためです.setCookieは配列ではなく変長パラメータを受け入れるため、applyで
  • を呼び出す.