簡體   English   中英

如何使用request和node.js訪問帶有querystring的頁面

[英]how to access pages with querystring using request and node.js

我使用Node.js為一個簡單的Web爬蟲編寫了代碼,並為在線教程收集了BuzzFeed測驗的信息。 它對於主頁( https://www.buzzfeed.com/quizzes )正常工作,但是當我嘗試在其他任何頁面(即https://www.buzzfeed.com/quizzes?page=4)上使用時 ),但沒有結果。 我不知道怎么了? 這是我的代碼:

var request = require('request');
var cheerio = require('cheerio');
var fs = require('fs');
var options = {
    method: 'GET',
    uri: 'https://www.buzzfeed.com/quizzes',
    qs: {
      page: 4
    }
}

request(options, function(error, response, html) {
    if(!error && response.statusCode == 200) {
      var $ = cheerio.load(html);

      $('div.card.js-feed-item').each(function( index ) { 
        var title = $(this).find('h2').text().trim();
        var link = $(this).find('a.link-gray').attr('href');
        var image = $(this).find('a.link-gray > div.js-progressive-image').attr('data-background-src');
        fs.appendFileSync('buzzfeed.txt', title + '\n' + link + '\n' + image + '\n\n');
      });
}});

基本上,如果我將其注釋掉:

qs: {
    page: 4
}

它工作正常。 我使用qs錯誤嗎?

查看頁面上完成的請求,實際上,您可以只刪除以下URL:“ https://www.buzzfeed.com/quizzes?render_template=0 ”,它為您提供了一個帶有2個字段的json:cards(信息數組)和nextPage(類似於/ quizzes?render_template = 0&page = 2),您可以使用我認為相同的數據。

看起來BuzzFeed服務器想要發送回壓縮的響應。 如果查看request模塊文檔,則可以找到以下選項:

gzip如果為true ,則添加一個Accept-Encoding標頭以從服務器請求壓縮的內容編碼(如果尚不存在),並在響應中解碼受支持的內容編碼。

因此,在您的情況下,只需將gzip: true添加到options對象即可。 但是要注意,取決於頁面顯示JS依賴頁面的程度,HTML可能不是您所期望的。


我是如何解決的? 好吧,基本上,如果您檢查返回的response對象(在if語句之外),則可以獲得一些非常有用的信息。

例如,我們可以通過使用response.request.url (或response.request.href )檢查請求url並(通過console.log或調試器)查看它是否正確構成了查詢字符串( ?page=4 )來檢查qs選項是否有效?page=4 ),所以這不是問題。

進一步挖掘,我們可以看到response.statusCode500response.body (或html參數)為{"message": "INTERNAL_ERROR"} 這似乎表明“服務器錯誤”,但是我們可以在瀏覽器中正常訪問頁面,因此實際上,由於某種原因,服務器似乎不喜歡我們如何形成請求。

在這樣的時候,值得檢查出response.headers ,在這里我們可以看到例如content-typeapplication/json (顯然不是您想要的)。 但是更有趣的是,有一個頭值vary報頭,其中一個值是Accept-Encoding這基本上是說“如果使用不同的Accept-Encoding頭再次發出此請求,您將獲得不同的響應”。 Accept-Encoding幾乎總是用於指定您可以處理的壓縮類型,其中gzip是服務器最常支持的壓縮類型,因此Node請求模塊提供了gzip選項。 如果打開瀏覽器devtools的網絡標簽並瀏覽到URL,則可以看到設置了相同的標頭(在Chrome瀏覽器中,通過“文檔”過濾請求以更輕松地找到它)。

編輯:您的原始代碼現在似乎對我有用,因此也許畢竟是服務器問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM