How to scrape .aspx site - web-scraping

I'm trying to scrape: http://search.bgc-group.com/Default.aspx
When I'm running my code, I'm always getting the first page.
My code:
var casper = require('casper').create({
verbose: true,
logLevel: "debug",
type: 'xpath',
});
casper.start('http://search.bgc-group.com/Default.aspx');
casper.thenOpen('http://search.bgc-group.com/Default.aspx', {
method: 'post',
data: {
'__EVENTARGUMENT': 'Page$4',
'__EVENTTARGET': 'ctl00$body$ctlJobListing1$gvJobListing',
'__EVENTVALIDATION': '',
'__PREVIOUSPAGE': '',
'__VIEWSTATE': ''
}
});
casper.then(function() {
this.echo('POSTED it.');
this.capture("test.png")
});
casper.run();
I've not left the __EVENTVALIDATION, __PREVIOUSPAGE and __VIEWSTATE fields blank in the actual code. Just skipped here as they were very long string.

You can do the following instead of the casper.thenOpen block:
var x = require('casper').selectXPath;
casper.thenClick("a[href*='Page$4']");
casper.waitForSelector(x("//td/span[text()='4']")); // might be unnecessary

Related

Fullcalendar V4: How to parse json received from ajax into event list

I'm trying to retrieve a list of events from an ajax call. I use the following code.
document.addEventListener("DOMContentLoaded", function()
{ var calendarEl = document.getElementById("id_d_agenda_1");
var calendar = new FullCalendar.Calendar(calendarEl, {
plugins: [ 'interaction', 'dayGrid', 'timeGrid', 'list' ],
header: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
},
defaultDate: '2019-08-12',
editable: true,
navLinks: true, // can click day/week names to navigate views
eventLimit: true, // allow "more" link when too many events
selectMirror: true,
select: function(arg) {
var title = prompt('Event Title:');
if (title) {
calendar.addEvent({
title: title,
start: arg.start,
end: arg.end,
allDay: arg.allDay
})
}
calendar.unselect()
},
events: function(arg) {
$.ajax({
url: 'd.php',
dataType: 'json',
data: {
cmd:'getdata',
start:arg.startStr,
end:arg.endStr,
tz:arg.timeZone,
component:'d_agenda_1',
},
success: function(doc) {
$(doc).each(function() {
calendar.addEvent( this );
})
}
})
}
})
calendar.render();
});
While debugging my javascript I can see the rows of events appear in 'doc'. First I tried to bulk add them to the agenda, but that didn't seem to work. Now I'm adding them one-by-one, buth they still don't appear. I have checked the this variable in the debugger and it shows a single event:
title:"value", start:"2019-08-01". In fact I'm using the sample list that comes with the package. Can someone point me to the right direction in what I'm doing wrong?
other options I tried (with no luck ;-):
I tried to leave the jquery out, but with similar effect:
success: function(doc) {
doc.forEach(function(value) {
calendar.addEvent( value );
})
}
success: function(doc) {
$(doc).each(function() {
calendar.addEvent({
title:this.title,
start:this.start
});
})
Not sure if it's helpful, but I added the selectable option and tested the select option. The calendar.addevent on the select: doesn't add the event either. Since this is copied from the sample i'm quite confused now. Fun part is that if you replace the ajax part with a regular [] expression that all works well. Even the selectable options, so there's definitely something wrong with my ajax implementation, in regards to this component.
According to the DOCS you need to have a successCallback that will return the events to the calendar.
Here is the docs https://fullcalendar.io/docs/events-function
Here is a simple Demo https://codepen.io/nasser-ali-karimi/pen/gOOJrWV?editors=0010
And in short, I can say that you need to set the events like this.
events: function(info, successCallback, failureCallback) {
successCallback([
{"resourceId":"a","title":"event 1","start":"2019-11-23","end":"2019-11-25"},
{"resourceId":"b","title":"event 3","start":"2019-11-24T12:00","end":"2019-11-25T06:00"},
{"resourceId":"b","title":"event 4","start":"2019-11-24T07:30","end":"2019-11-24T09:30"},
{"resourceId":"b","title":"event 5","start":"2019-11-24T10:00","end":"2019-11-24T15:00"},
{"resourceId":"a","title":"event 2","start":"2019-11-24T09:00","end":"2019-11-24T14:00"}
])
}
you didn't mention the events data that comes from Ajax request, so I can say you need to provide the data like what said on docs.
Addition
Note: Event's date are on 11/28 and 11,29 so navigate to those dates to see the events.
Demo https://codepen.io/nasser-ali-karimi/pen/qBBGVbG?editors=0010
events: function(info, successCallback, failureCallback) {
var arrevents = [];
jQuery.get( "https://api.myjson.com/bins/16ubhe", function( data ) {
// var response = JSON.parse(data);
// $.each(response, function(k, v) {
// arrevents.push(v);
// });
arrevents = data;
successCallback(arrevents);
});
},

Meteor collection2 - all validation messages

I am looking for a way to retrieve all validation errors. (I'm using Collection2 and SimpleSchema)
Consider this code:
Foo.insert({
title: '',
description: ''
}, function(error, result) {
console.error(error);
});
output:
{
message: 'Title may not be empty.',
invalidKeys: [
0: {
name: 'title',
type: 'required',
value: ''
},
1: {
name: 'description',
type: 'required',
value: ''
}
]
}
I would like to have all the error messages that are related to validation.
Unfortunately I couldn't find any solution for this.
SOLUTION:
I've found a satisfiable solution
Foo.simpleSchema().namedContext().keyErrorMessage('title');
I ran into the same problem and my solution was to insert said errors into a client mongo error collection which would then display the errors to the user. The following is what I came up with:
Schema
Schema.newUser = new SimpleSchema({....});
Client Side Validation
function tokenRegistration (newUser) {
var valContext = Schema.newUser.namedContext('tokenRegForm');
if (!valContext.validate(newUser)) {
var keys = valContext.invalidKeys();
_.each(keys, function (value) {
var error = value.name,
message = valContext.keyErrorMessage(error);
return ErrorMessage.insert({errormessage: message})
});
}
}

dgrid JsonRest store not working

I have the following:
require([
"dojo/dom",
"dojo/on",
"dojo/store/Observable",
"dojo/store/JsonRest",
"dojo/store/Memory",
"dgrid/OnDemandGrid"
], function (dom, on, Observable, JsonRest, Memory, OnDemandGrid) {
var store = new JsonRest({
target: 'client/list',
idProperty: 'id'
});
var grid = new OnDemandGrid({
columns: {
"id": "ID",
"number": "Name",
"description": "Description"
},
sort: "lastName",
store: store
}, "grid");
});
client/list is a rest url returning a json object {data:[...]}, but the content of the list never shows up :/
I think the problem is caused by the async data loading, because with a json hard coded object the content show up
EDIT :
I've succeeded in achieving this by using a dojo/request, but the JsonRest shouldn't normally act the same way ? Can someone point me to the right direction ?
require([
'dojo/dom',
'dojo/on',
'dojo/store/Memory',
'dojo/request',
'dgrid/OnDemandGrid'
], function (dom, on, Memory, request, OnDemandGrid) {
request('client/list', {
handleAs: 'json'
}).then(function (response) {
// Once the response is received, build an in-memory store with the data
var store = new Memory({ data: response });
// Create an instance of OnDemandGrid referencing the store
var grid = new OnDemandGrid({
store: store,
sort: 'id', // Initialize sort on id, ascending
columns: {
'id': 'ID',
'number': 'Name',
'description': 'Description'
}
}, 'grid');
console.log(store);
on(dom.byId('queryForm'), 'input', function (event) {
event.preventDefault();
grid.set('query', {
// Pass a RegExp to Memory's SimpleQueryEngine
// Note: this code does not go out of its way to escape
// characters that have special meaning in RegExps
description: new RegExp(this.elements.last.value, 'i')
});
});
on(dom.byId('queryForm'), 'reset', function () {
// Reset the query when the form is reset
grid.set('query', {});
});
});
});
Ok problem found :/
My "client/list" url was returning a json object like this:
{data: [{id:"1", label: "test"}, {id:"2", label: "test"}]}
Turns out that the JsonRest object is already encapsulating data in a data node, so by returning a json like this:
{[{id:"1", label: "test"}, {id:"2", label: "test"}]}
everything worked fine :)

Yammer Open-graph and Commenting

I have this code, no API nor nothing, I simply would like to get a Group ID inside here for it to be the default option for where to share the comment and embed the comment stream on Yammer, is this even possible? Is there a way to block the possibility of selection from all your groups and leave it to just one?
<script>
yam.connect.embedFeed({
container: "#embedded-feed",
feedType: "open-graph",
config: {
header: true,
footer: false,
promptText: "Remember to select a Group and/or person",
showOpenGraphPreview: true,
}
});
</script>
The Code is working, but I just need to filter that option
Thank you
We just released this feature. Documentation is to be updated very soon, use "defaultGroupId" inside your config to get your group selected.
i have done a simple implementation like this.
var generateYammerFeeds = function(title, description) {
try {
yam.connect.embedFeed({
container: "#yammerDiscussion",
network: "abc.com",
feedType: "open-graph",
objectProperties: {
fetch: true,
private: false,
ignore_canonical_url: false,
url: location.href,
type: "page",
title: title,
image: '',
description: description
},
config: {
header: true,
footer: true,
showOpenGraphPreview: false,
defaultToCanonical: true,
hideNetworkName: true,
promptText: "Ask a Question",
defaultGroupId: 121212
}
});
return true;
} catch (e) {
return null;
}
};

$scope issue on ngGridEventEndCellEdit event when i rollback data

I probably misunderstood something but here is my problem on plunker.
I put the relevant code here anyway:
var app = angular.module('myApp', ['ngGrid']);
app.controller('MyCtrl', function($scope) {
var cellNameEditable =
'<cell-template model=COL_FIELD input=COL_FIELD entity=row.entity></cell-template>';
var cellNameDisplay =
'<div class="ngCellText" ng-class="col.colIndex()">{{row.getProperty(col.field)}}</div>';
$scope.myData= [{"id":1,"code":"1","name":"Ain"},{"id":2,"code":"2","name":"Aisne"},{"id":3,"code":"3","name":"Allier"},{"id":4,"code":"5","name":"Hautes-Alpes"},{"id":5,"code":"4","name":"Alpes-de-Haute-Provence"},{"id":6,"code":"6","name":"Alpes-Maritimes"},{"id":7,"code":"7","name":"Ardèche"},{"id":8,"code":"8","name":"Ardennes"},{"id":9,"code":"9","name":"Ariège"},{"id":10,"code":"10","name":"Aube"}];
$scope.gridOptions = {
data: 'myData',
multiSelect: false,
enableCellSelection: true,
enableRowSelection: false,
enableCellEditOnFocus: false,
rowHeight: 100,
columnDefs: [
{field:'id', displayName:'Id', visible: false},
{field:'code', displayName:'Code', enableCellEdit:true},
{
field:'name', displayName:'Name', enableCellEdit:true,
cellTemplate: cellNameDisplay,
editableCellTemplate: cellNameEditable
}
]
};
});
app.directive('cellTemplate', function () {
var cellTemplate =
'<div><form name="myForm" class="simple-form" novalidate>' +
'<input type="text" name="myField" ng-input="localInput" ng-model="localModel" entity="entity" required/>' +
'<span ng-show="myForm.myField.$error.required"> REQUIRED</span>' +
'localModel = {{localModel}} localInput = {{localInput}} entity = {{entity}}' +
'</form></div>';
return {
template: cellTemplate,
restrict: 'E',
scope: {
localModel:'=model',
localInput:'=input',
entity:'=entity'
},
controller: function ($scope) {
$scope.$on('ngGridEventStartCellEdit', function (event) {
console.log('cellTemplate controller - ngGridEventStartCellEdit fired');
$scope.oldEntity = angular.copy(event.currentScope.entity);
$scope.oldValue = angular.copy(event.currentScope.localModel);
});
$scope.$on('ngGridEventEndCellEdit', function(event) {
console.log('ngGridEventEndCellEdit fired');
if(event.currentScope.myForm.$valid) {
if(!angular.equals($scope.oldEntity, event.currentScope.entity)) {
alert('data saved !');
}
} else {
$scope.localModel = angular.copy($scope.oldValue);
$scope.localInput = angular.copy($scope.oldValue);
$scope.entity = angular.copy($scope.oldEntity);
}
});
}
};
});
Then explanations:
I have a ng-grid and based on the official example named "Excel-like Editing
Example" but with enableCellEditOnFocus option turned to false.
The cell "name" is defined in a directive containing a form to handle
data validation before updating the model.
I want to implement this behavior: When a user put invalid data, the
directive display error message and when the user leave the field, the
directive rollback data. If everything ok then I let the data updated.
The rollback part does not work. On the given plunker line 67 to 72 (last block on the code given here) it
fails to retore data. But my binding is with "=" so it should. Or maybe
because I am on the ngGridEventEndCellEdit event it breaks the links ?
I really don't understand why it fail.
So to reproduce my issue: enter in modification on a name cell, delete
all the data, REQUIRED is shown, then go out from the cell -> model is
not rolled back.
If you use a custom template, you should emit ngGridEventEndCellEdit event.

Resources