1

アップデート:

jQuery の実行に失敗したページで使用されているタグ「base」を見つけました。Web サイトにそのタグが含まれている場合、jsdom は機能しません。理由はわかりませんが。

<base href="http://bbs.18183.com/" />

これを確認するために、新しい HTML ファイルを作成して内部に配置すると、jsdom が失敗します。


私は現在 Node.js で遊んでいます。Node.js と jQuery を使用して Web ページをスクレイプする方法を読んだ後、自分用に作成することにしました。

そこで、express、jsdom などをインストールしましたが、Web ページをスクレイピングするのに非常に便利であることがわかりました。しかし、後で特定のページをスクレイピングできないという奇妙な状況を発見しました。代わりに、次のようなエラーが表示されます。

          var title = $('title').text();
                      ^
TypeError: undefined is not a function
    at H:\animalwar\personal\node\getter\app.js:82:23
    at exports.env.exports.jsdom.env.scriptComplete (H:\animalwar\personal\node\
getter\node_modules\jsdom\lib\jsdom.js:207:39)
    at process.startup.processNextTick.process._tickCallback (node.js:244:9)

これが私のコードです:

request({
  url:'http://bbs.18183.com/'},
  function (err, response, body) {
    if(err && response.statusCode !== 200){
      console.log('Connection Failure! Fuck GFW');
      res.end('Connection Failure! Fuck GFW');
      return;
    }
    jsdom.env({
      html: body,
      scripts: ['jquery.js']
      }, function(err, window){
        //Use jQuery just as in a regular HTML page
        var $ = window.jQuery;
        var title = $('title').text();
        console.log('SUCCESSFULLY GOT: ', title );
        res.end(title);
      }
   );
});

この場合、 Web サイト " http://bbs.18183.com/ " は機能していませんが、他の多くの Web サイトは機能しています。たとえば、「http://www.18183.com/」に変更すると、機能します。

「$」の定義の競合が原因だと思いますが、後で jsdom.env を使用すると、ページが単なる DOM ツリーであることに気付きました。$ を他の名前に変更しても、まだ機能しません。

誰もこれについて何か知っていますか?

4

1 に答える 1

2

ここで何が起こっているかがわかります。これは完全なバグではありませんが、どこが予想外なのかがわかります。何が起こっているかは次のとおりです。

scripts: ['jquery.js']「挿入」に変換され<script src="jquery.js">ます。jsdom がを検出すると、現在のドキュメントの URL を基準にし<script src="jquery.js">てロードを試みます。jquery.js

タグのないドキュメントで<base>は、URL ではなく HTML フラグメント文字列を使用して明示的に読み込むと、ドキュメントの URL はfile://現在のスクリプトに対応する URL に設定されます。そしてjquery.js、あなたの現在のスクリプトのすぐ隣にあるに違いないので、うまく機能します:<script src="jquery.js">問題なく解決します。

ただし、<base>タグ付きのドキュメントでは、ドキュメントの URL がそのベースに設定されます。したがって<script src="jquery.js">、この場合は loading に変換され、ローカルホストのポート 80 で実行されているサーバーで利用可能な を<base href="http://localhost/jquery.js">持っていないに違いありません。したがって、これは失敗します。jquery.js

修正は、より明確にすることです。私は次のようなものを提案します

var path = require("path");

jsdom.env({
  html: myHTML,
  scripts: [path.resolve(__dirname, "jquery.js")],
  done: function (errors, window) {
  }
});

errors変数を確認した場合、手がかりとなるエラーが表示される可能性があることに注意してください。そのようなエラー処理コードはないようです。

于 2013-06-03T07:01:16.503 に答える