iT邦幫忙

0

RangeError [ERR_HTTP_INVALID_STATUS_CODE]: Invalid status code: undefined

如題,
運行程式碼後得到以下錯誤訊息
https://ithelp.ithome.com.tw/upload/images/20190803/20111873n4TEC782o0.jpg

有上網找過解決方法,但是都沒有用
https://teamtreehouse.com/community/rangeerror-invalid-status-code-undefined-when-linking-to-another-page
https://reviewdb.io/questions/1537629072146/getting-rangeerror-err_http_invalid_status_code-invalid-status-code-3

以下是POST過去的DATA

{"pname" : "book"}

懇請各位大大解答,感謝

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

1
dragonH
iT邦超人 5 級 ‧ 2019-08-03 12:56:13
最佳解答

雖然已經沒問題了

這個就當參考吧 /images/emoticon/emoticon01.gif

const Express = require('express');
const axios = require('axios');
const cheerio = require('cheerio');
const app = Express();
const router = Express.Router();
const port = 9999;

router.get('/search/:keyword', async (req, res) => {
  await crawlPage(req.params.keyword)
    .then(result => res.status(200).send({ keyword: req.params.keyword, result }).end())
    .catch((err) => {
      console.log(err);
      res.status(500).send({ message: err }).end()
    });
});

const crawlPage = (keyword) => {
  return new Promise((resolve, reject) => {
    const baseUrl = 'https://www.google.com/search';
    const query = {
      // ei: 'at5DXeq3H8SSr7wPzc-56AU',
      q: keyword,
      // oq: 'it邦幫忙',
      // gs_l: 'psy-ab.3..0l9j0i7i30.2043.2043..3196...0.0..0.52.52.1......0....1..gws-wiz.h4Uim--P2-c',
      // ved: '0ahUKEwjqlLPEzePjAhVEyYsBHc1nDl0Q4dUDCAo',
      // uact: 5
    };
    const options = {
      headers: {
        'accept-language': ' zh-TW,zh;q=0.9,en-US;q=0.8,en;q=0.7',
        'user-agent': ' Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36',
      }
    };
    const searchUrl = new URL(baseUrl);
    const searchQuery = new URLSearchParams(query);
    searchUrl.search = searchQuery;
    axios.get(searchUrl.href, options)
      .then((res) => {
        const $ = cheerio.load(res.data);
        resolve($('#resultStats').text());
      })
      .catch(err => reject(err));
  });
};

app.use(router);
app.listen(port, () => {
  console.log(`Server is listening at http://127.0.0.1:${port}`);
});

網址輸入

http://127.0.0.1:9999/search/${要搜尋的關鍵字}

e.g.

http://127.0.0.1:9999/search/it邦幫忙

就可以拿到結果

{
    keyword: "it邦幫忙",
    result: "約有 1,140,000 項結果 (搜尋時間:0.27 秒) "
}
看更多先前的回應...收起先前的回應...
p39212053 iT邦新手 4 級 ‧ 2019-08-03 14:07:05 檢舉

大大你好,我換了一個寫法
crawler.js

const axios = require('axios');
const cheerio = require('cheerio'); //用 cheerio 擷取我們頁面要的部份

//crawler
const crawlPage = (pname) => {
    const baseUrl = 'https://www.google.com/search';
    const query = {
      q: pname
    };
    const options = {
      headers: {
        'accept-language': ' zh-TW,zh;q=0.9,en-US;q=0.8,en;q=0.7',
        'user-agent': ' Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36',
      }
    };
    
    const searchUrl = new URL(baseUrl);
    const searchQuery = new URLSearchParams(query);
    searchUrl.search = searchQuery;
    axios.get(searchUrl.href, options)
      .then((res) => {
        var $ = cheerio.load(res.data);
        console.log($('#resultStats').text());
        const total_number = $('#resultStats').text().substring($('#resultStats').text().indexOf("有")+2,$('#resultStats').text().indexOf("項")-1).split(",").join("");
        return total_number;
    }).catch(err => console.log(err));
};
module.exports = {crawlPage};

app.js

const crawler = require("./crawler");
//create
app.post('/',(req,res,next)=>{
  // Document to be inserted
  const pname = req.body.pname;
  console.log(pname+"pname");
  const total_number = crawler.crawlPage(pname);
  console.log(total_number+"total_number");
  const obj = { pname : pname , total_number : total_number };
  // insert document within collection
  db.getDB().collection(collection).insertOne(obj,(err,result)=>{
    if(err){
      const error = new Error("Failed to insert Document");
      res.status = 400;
      next(error);
    }
    else
    {
      //res.json({result : result, document : result.ops[0],msg : "Successfully inserted!!!",error : null});
      console.log(result+'Successfully inserted');
      
    }
    });
  
});

這樣total_number收到的是undefined (இ﹏இ`。)
函式好像最後才會跳到
axios.get(searchUrl.href, options)此函示執行

請問一定要使用promise中的非同步寫法嗎

dragonH iT邦超人 5 級 ‧ 2019-08-03 14:25:56 檢舉

不然 total_number 不會等你的 crawlPage

執行完成才往下走

p39212053 iT邦新手 4 級 ‧ 2019-08-03 15:56:52 檢舉

大大不好意思,再打擾您,
app.js

router.post('/', async (req, res) => {
  await crawlPage(req.body.pname)
    .then( total_number =>
      const obj = { pname : req.body.pname, total_number };
      db.getDB().collection(collection).insertOne(obj,(err,result)=>{
        if(err){
          const error = new Error("Failed to insert Document");
          res.status = 400;
          next(error);
        }
        else
        {
          //res.json({result : result, document : result.ops[0],msg : "Successfully inserted!!!",error : null});
          console.log(result+'Successfully inserted');
          
        }
      }
      )
    .catch((err) => {
      console.log(err);
      res.status(500).send({ message: err }).end()
    });
    
});

我想直接在裡面的json資料存進mongoDB裡面,可是不知道為什麼這樣寫不行 QQ ...

dragonH iT邦超人 5 級 ‧ 2019-08-03 16:17:44 檢舉

有錯誤嗎

p39212053 iT邦新手 4 級 ‧ 2019-08-03 16:24:25 檢舉

他會有
SyntaxError: Unexpected token const
https://ithelp.ithome.com.tw/upload/images/20190803/20111873qzlA2pVoEd.jpg

抱歉初學JS不太會 ...

dragonH iT邦超人 5 級 ‧ 2019-08-03 16:38:56 檢舉

你要用 括號刮起來

如果後面不是單純 return 的話

.then((total_number) => { ... })

另外

我比較喜歡用 monk 來連 mongodb

const Express = require('express');
const axios = require('axios');
const cheerio = require('cheerio');
const app = Express();
const monk = require('monk');
const router = Express.Router();
const port = 9999;
const db = monk('127.0.0.1:27017/demo');

router.get('/search/:keyword', async (req, res) => {
  const collection = db.get('demo1');
  const result = await crawlPage(req.params.keyword)
    .then(result => result)
    .catch(err => res.status(500).send({ message: err }).end());
  await collection.insert({ keyword: req.params.keyword, result });
  res.status(200).send({ keyword: req.params.keyword, result }).end();
});

database

/* 1 */
{
    "_id" : ObjectId("5d4546bf2bdb56242498c06d"),
    "keyword" : "it邦幫忙",
    "result" : "約有 1,140,000 項結果 (搜尋時間:0.26 秒) "
}

/* 2 */
{
    "_id" : ObjectId("5d45478d80689222488a62c9"),
    "keyword" : "youtube",
    "result" : "約有 11,180,000,000 項結果 (搜尋時間:0.53 秒) "
}
p39212053 iT邦新手 4 級 ‧ 2019-08-03 17:11:07 檢舉

感謝大大您的指點與幫忙,monk package讓程式碼簡潔很多,多謝推薦! ฅ•ω•ฅ

dragonH iT邦超人 5 級 ‧ 2019-08-03 17:12:03 檢舉

/images/emoticon/emoticon12.gif

我要發表回答

立即登入回答