Scraping website using node js using auth - node.js

var getMatches = function(){
var sait = 'https://www.website.com'
request({ url: sait, jar: true}, function(error, response, html){
if(!error){
var $ = cheerio.load(html)
var count = ($('.TheMatch').length)
for(var i = 2; i< count + 2 ; i++){
var live = ($('.TheMatch:nth-child('+i+') .LiveStatus').text())
var nameMatch = ($('.TheMatch:nth-child('+i+') .MDxEventName').text())
var time = ($('.TheMatch:nth-child('+i+') .DateTime').text().substring(8))
var websiteCount = ($('.TheMatch:nth-child('+i+') .TotalBookies').text())
if((websiteCount >= 25) && (live.length === 0) ){
console.log('match ' + nameMatch)
console.log('count Websites ' + websiteCount)
}
}}})}
i want to make auth on this website and save the cookie how can i do it ? and save the cookie so everytime i parse dont gonna need to log in ?

Well, I did similar task. But problem is that it is always site specific. Anyway, the way to do it is to use request library to make a post request to website's auth endpoint. Then response object will contain appropriate cookies like sessionID or something. Then you save this cookie and do a new request to page you wanted from the beginning. Here is documentation about cookies in request module: https://github.com/request/request#requestcookie. That worked for me fine.
How to get:
request.post({ url: "website/signin",
form: {
login: 'login',
password: "password",
remember: 1
}
}, function(err, httpResponse, body) {
var cooka = false;
var cookies = httpResponse.headers['set-cookie'];
if (typeof cookies != "undefined") cooka = cookies[0];
if (typeof cooka != "undefined" && cooka != false) {
self.sessionId = cooka.substring(10, cooka.indexOf(";"));
} else {
return self.emit("error", "Can't get session id");
}
});
How to set:
var options = { uri: "desired url" };
var j = request.jar();
if (worker.source == "coquette") {
var cookie = request.cookie('PHPSESSID=' + worker.sessionId);
j.setCookie(cookie, url);
options.jar = j;
}
request.get(options, function(error, response, body) {
if (error || response.statusCode != 200) {
} else {
// work with body body
}
});

Related

Strange 401 error in nodejs. when calling 2 API it gives auth error

When I am calling one API from the nodejs it is giving proper reply. But when I am adding one more call it is giving 401 error. I dont know if I have to close some parameter before calling another request.
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
var request = require('request')
var username = "shruti111";
var password = 'Welcome1';
var planId;
baseUrl = 'https://50d5a18993c046e585b90bc8cc5e1f80-jcs.oci.cloudonline.ml:443';
var baseUrlwoHttps = baseUrl.substring(8);
process.env["NO_PROXY"] = baseUrlwoHttps;
var getUrl = baseUrl + '/IMCMCSREST/rest/v1/PlannedCosts';
var options = {
url: getUrl,
auth: {
user: username,
password: password
}
}
request(options, function (err, res, body) {
if (err) {
console.dir(err)
return
}
var json = JSON.parse(body);
var arr = [];
for (i = 0; i < json.items.length; i++) {
if (json.items[i].PlanCode == 'Material Cost Planning - PO')
planId = json.items[i].PlanId;
//arr.push(json.items[i].PlanId, json.items[i].PlanCode);
}
console.log(planId);
})
Upto this point it is working properly. If I add below code in the same file it gives 401 error for both call. Otherwise it runs properly.
var getUrl = baseUrl + 'IMCMCSREST/rest/v1/PlannedCosts/' + planId + '/ child / CmiCpPlanCostTypesView';
var options = {
url: getUrl,
auth: {
user: username,
password: password
}
}
request(options, function (err, res, body) {
if (err) {
console.dir(err)
return
}
console.log(body);
var json = JSON.parse(body);
console.log(json);
var arr = [];
var x;
for (i = 0; i < json.items.length; i++) {
arr[i] = json.items[i].CostTypeId;
//arr.push(json.items[i].PlanId, json.items[i].PlanCode);
}
console.log(arr[i]);
})
I think the first problem here is the plandId variable you're using on second request does not have a value. What you can try is calling the second request on the callback of first request.
Another problem seems to be you are redefining existing variables, though its not fully clear as you didn't show the file as a whole.

Can't set headers after they are sent in get request

router.get('/getpostcode', function(req, res){
console.log(req.query.suburb);
var options = {
url: 'http://apiurl?suburb=' + req.query.suburb + "&state=" + req.query.state ,
headers: {
'auth-key': key
}
}
request(options, callback);
function callback(error, response, body){
if(!error && response.statusCode == 200){
info = JSON.parse(body);
info = info.localities.locality;
if( Object.prototype.toString.call( info ) == '[object Array]' ){
for ( var x = 0 ; x < info.length ; x++ ){
var locx = info[x].location;
var qsuburb = req.query.suburb;
if( locx == qsuburb.toUpperCase() ){
res.send( { 'postcode': info[x].postcode } );
}
}
} else if (Object.prototype.toString.call( info ) != '[object Array]') {
var locx = info.location;
var qsuburb = req.query.suburb;
if ( locx == qsuburb.toUpperCase() ){
res.send( { 'postcode': info.postcode } );
}
}
}
}
});
So, I am trying to request data from an API and then based on that data, I am then sending some data back. My code is as above.
Unfortunately, in the callback function, when I am running a loop to find a specific element that I will then send back to the client, when sending that element to client, I am getting the error as shown in the title.
This does not occur when there is no loop and I simply send one element of the data back.
Any ideas on what this could be?
You are sending response more than one for one request, write res.send or JSON outside the loop.
for (var x = 0; x < info.length; x++) {
var locx = info[x].location;
var qsuburb = req.query.suburb;
var postcodes = [];
if (locx == qsuburb.toUpperCase()) {
postcodes.push({
'postcode': info[x].postcode
});
}
res.json(postcodes);
}
You are reaching the res.send function call at least twice in your flow and this is not allowed. That function must be called once to send the response to the client.
Yeah, As #Rahul said, It is not allowed to send response more than one time for the same request - You must be getting same post code, so you either need to store your postcode in a variable and send it after loop overs or you can use a break. Though it is not advisable to use a break in complex loops in the pretty simple loop you can leverage its usage.
for (var x = 0; x < info.length; x++) {
var locx = info[x].location;
var qsuburb = req.query.suburb;
if (locx == qsuburb.toUpperCase()) {
res.send({
'postcode': info[x].postcode
});
break;
}
}
Or as following:
for (var x = 0; x < info.length; x++) {
var locx = info[x].location;
var qsuburb = req.query.suburb;
vat postcode = = null;
if (locx == qsuburb.toUpperCase()) {
postcode = info[x].postcode
}
}
res.send({
postcode
});

using node jsrequest for the flickr API

I'm using the node js request function to access the following URL for the flickr API
https://www.flickr.com/services/oauth/access_token?oauth_token=X&oauth_verifier=X&oauth_consumer_key=X&oauth_nonce=X&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1468959629921&oauth_version=1.0&oauth_signature=X
For some reason, I'm getting a response timeout. What would you recommend that I do to fix this?
Here's the code
request(url, function (e, r, body) {
if (!e && r.statusCode === 200) {
var tokens = qs.parse(body);
console.log('test1');
var key = self.PLATFORM_TYPE + '_' + tokens.user_nsid;
var user = {
tokens: tokens,
key: key,
platform: self.PLATFORM_TYPE
};
deferred.resolve(user);
} else {
deferred.reject(body);
}
});

How to wait a request response and return the value?

When I use a request module in node.js server, I have some problem such as wait and return.
I would like to receive a "responseObject" value at requestController.
To solve this problem, I have search the best way but I still do not find it.
How can solve this problem?
Thank in advance!! :)
=========================================================================
var requestToServer = require('request');
function getRequest(requestObject) {
var urlInformation = requestObject['urlInformation'];
var headerInformation = requestObject['headerInformation'];
var jsonObject = new Object( );
// Creating the dynamic body set
for(var i = 0; i < headerInformation.length; i++)
jsonObject[headerInformation[i]['headerName']] = headerInformation[i]['headerValue'];
requestToServer({
url : urlInformation,
method : 'GET',
headers : jsonObject
}, function(error, response ,body) {
// todo response controlling
var responseObject = response.headers;
responseObject.body = body;
});
}
// Controlling the submitted request
exports.requestController = function(requestObject) {
var method = requestObject['methodInformation'];
var resultObject = null;
// Selecting the method
if(method == "GET")
resultObject = getRequest(requestObject);
else if(method =="POST")
resultObject = postRequest(requestObject);
else if(method == "PUT")
resultObject = putRequest(requestObject);
else if(method == "DELETE")
resultObject = deleteRequest(requestObject);
console.log(JSON.stringify(resultObject));
}
You can use callbacks in the following way.
function getRequest(requestObject, callback) {
// some code
requestToServer({
url : urlInformation,
method : 'GET',
headers : jsonObject
}, function(error, response ,body) {
// todo response controlling
var responseObject = response.headers;
responseObject.body = body;
callback(responseObject);
});
}
And
// Controlling the submitted request
exports.requestController = function(requestObject) {
var method = requestObject['methodInformation'];
// Selecting the method
if(method == "GET")
getRequest(requestObject, function(resultObject){
console.log(JSON.stringify(resultObject));
});
//some code
}
Hope, it helps.

I am unable to convert http.get image into base 64

app.getImage = function() {
var image = Meteor.http.get("https://turtlerock-discourse.global.ssl.fastly.net/user_avatar/talk.turtlerockstudios.com/takran/45/879.png", {
});
var prefix = "data:image/png;base64,";
var imagebase64 = new Buffer(image.content, 'binary').toString('base64');
imagebase64 = prefix + imagebase64;
console.log(imagebase64);
return imagebase64;
}
but I am not seeing results,
any help?
This is a dummy text for the error.
a pure Meteor solutions:
var response = HTTP.call('GET', url,{npmRequestOptions: { encoding: null }})
var data = "data:" + response.headers["content-type"] + ";base64," + new Buffer(response.content).toString('base64');
This is how I fixed this issue.
app.getImage = function(){
var myrequest = request.defaults({ encoding: null });
var fut = new Future();
var options = {
"url" : "https://any.domain.com/any.png"
}
myrequest.get(options, function (error, response, body) {
if (!error && response.statusCode == 200) {
var data = "data:" + response.headers["content-type"] + ";base64," + new Buffer(body).toString('base64');
fut.return(data);
}
else
fut.return(null);
});
return fut.wait();
}
I was assuming this solution should have come with meteor code itself,
but it doesn't,
I had to use nodejs way to do it.
I will still be waiting for someone to post an answer based on pure meteor way.

Resources