How to get multi links and follow these links in Phantomjs? - web-scraping

I'm beginner at Phantomjs so many problems i can't solve them myselft. Would you mind helping me to solve this problem? I have problem about getting multi dynamic urls by Phantomjs.
Example:
-- My index.html is:
<!DOCTYPE html>
<html>
<body>
<h1>Homepage</h1>
<ul>
<li>Laptop</li>
<li>Tablet</li>
</ul>
</body>
</html>
-- My laptop.html file (tablet.html file as the same) is:
<!DOCTYPE html>
<html>
<body>
<h1>Laptop Page</h1>
<div class="productRow">Product of Laptop 1</div>
<div class="productRow">Product of Laptop 2</div>
</body>
</html>
I want to print like this:
Category Name: Laptop
Product: Product of Laptop 1
Product: Product of Laptop 2
....
Category Name: Tablet
Product: Product of Tablet 1
Product: Product of Tablet 2
...
It's mean that i want to get content of this url http://abc.com/test/. Then i will get links of ( UL LI A HREF). And then i will follow those links to get content their sub page automatically.
This is my sample code by Phantomjs:
var page = require('webpage').create();
var url = 'http://localhost/test';
page.open(url, function() {
//Get parent link
var parent = page.evaluate(function() {
var test = document.querySelectorAll('li a');
return Array.prototype.map.call(test, function(elem) {
return elem.href;
});
});
for(var i=0; i < parent.length; i++){
//Print parent link
console.log("Parent link:" + parent[i]);
//Then open child link
page.open(parent[i],function(){
//console.log(document.title);
var child = page.evaluate(function() {
var test = document.querySelectorAll('div.productRow');
return Array.prototype.map.call(test, function(elem) {
return elem.innerHTML;
});
});
console.log(child.length);
phantom.exit();
});
}
});
Why's console.log(child.length) = 0? Can you help me? Thanks for your help.

Try it just like this, it should work. Of course I am assuming, that the parent array is properly filled with correct links.
var child = page.evaluate(function() {
return [].map.call(document.querySelectorAll('div.productRow'), function(div) {
return div.innerHTML;
});
});

Related

Get Contact form 7 multiple image name

I have created a multiple image selection button with this plugin.
https://wordpress.org/plugins/multifile-upload-field-for-contact-form-7/
below is my contact form 7 code.
<div class="file wrap">
<div class="fileText">Upload Photos</div>
[multifile multi-images id:img_upload]
</div>
<div class="file_names">No file selected</div>
Now i want that if user will select multiple images then all image names will come like this
xyz.jpg, abc.png, pqr.jpg at the place of "No file selected"
You can do this with jQuery. Add this code in your js file.
jQuery('.file input[type="file"]').on('change', function () {
var names = [];
for (var i = 0; i < jQuery(this).get(0).files.length; ++i) {
names.push(jQuery(this).get(0).files[i].name);
}
jQuery(this).parent().parent().parent().parent().find('.file_names').text(names.join(", "));
});
Add this at the bottom of your form:
<script>
jQuery(document).ready(function($) {
$('.wpcf7-multifile').first().on('change', function() {
var files = $(this).prop("files");
var names = $.map(files, function(val) { return val.name; });
$('.file_names').html(names.join(', '));
});
});
</script>

CSS Issue with Node.JS / EJS

I know similar questions have been asked before, but I've had a good look through & unfortunately none of the answers are helping me.
My CSS file is being ignored in certain circumstances.
So in my app.js file I have this code, defining my view engine setup
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
In my index.js file I have the following the code for UserList page
/* GET Userlist page. */
router.get('/userlist', function(req, res) {
var db = req.db; // (1) Extract the db object we passed to our HTTP request
var collection = db.get('usercollection'); // (2) Tell our app which collection we want to use
// (3) Find (query) results are returned to the docs variable
collection.find({},{},function(e,docs){
res.render('userlist', { "userlist" : docs }); // (4) Render userlist by passing returend results to said variable
});
});
Finally, my userlist.ejs page looks like this:
<!DOCTYPE html>
<html>
<head>
<title>User List</title>
<link rel='stylesheet' href='/stylesheets/style.css' type="text/css" />
</head>
<body>
<h1>User List</h1>
<ul>
<%
var list = '';
for (i = 0; i < userlist.length; i++) {
list += '<li>' + userlist[i].username + '</li>';
}
return list;
%>
</ul>
</body>
</html>
But when I run my page the CSS file is not loaded. However if I exclude this code:
<%
var list = '';
for (i = 0; i < userlist.length; i++) {
list += '<li>' + userlist[i].username + '</li>';
}
return list;
%>
The CSS file is loaded and applied without issue. Can anyone tell me why this is please? Apologies for the newbie question, but I've been trying to figure this out for ages.
I should mention the 'h1' tags are ignored too. The only thing rendered is the list items.
Not sure if its relevant, but my app is connecting to MongoDB to return the user data.
Any assistance would be very much appreciated!
Thank you!
Make sure that your CSS file is either defined as an endpoint in your index.js file or make sure that public/stylesheets/style.css exists so it can be loaded through the app.use(express.static(path.join(__dirname, 'public'))); command.

Add dropdown box in Google site

I have some data in Google sheet.
How can i extract the data based on user request as per a dropdown box and generate it in Google Site.
The challenges iam faced with.
Prob_1- using a dropdown box in Google site
Prob_2- generate dynamic data ( or table ) in google site from the Google spreadsheet.
Analysis_1 - I have made a detailed study and understood that only using a third party plugin , i can make a select box. As a newbiew, needed some guidelines based on this.
Is it not possible without any third party plugin.
Analysis_2- Or is there any other option to generate an action based on a selection in google site. I understood that scripting is not possible in google site. So how shall i make a button click action.
Need some guidelines on this.
This is some javascript code to load options into a select box.
function updateSelect(vA)//array of values that go into the drop down or select box
{
var select = document.getElementById("sel1");
select.options.length = 0;
for(var i=0;i<vA.length;i++)
{
select.options[i] = new Option(vA[i],vA[i]);
}
}
This is html for the select box.
<select id="sel1" style="width:125px;height:35px;margin:10px 0 10px 0;">
<option value="" selected></option>
</select>
Seem pretty simple to me.
Here's a more complete solution.
Code:
function getSelectOptions()
{
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Options');
var rg=sh.getDataRange();
var vA=rg.getValues();
var options=[];
for(var i=0;i<vA.length;i++)
{
options.push(vA[i][0]);
}
return vA;
}
function showSidebar()
{
var userInterface=HtmlService.createHtmlOutputFromFile('f');
SpreadsheetApp.getUi().showModelessDialog(userInterface, 'The Drop Down with No Options now has options.');
}
f.html
<!DOCTYPE html>
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(function() {
$('#txt1').val('');
google.script.run
.withSuccessHandler(updateSelect)
.getSelectOptions();
});
function updateSelect(vA)
{
var select = document.getElementById("sel1");
select.options.length = 0;
for(var i=0;i<vA.length;i++)
{
select.options[i] = new Option(vA[i],vA[i]);
}
}
console.log("My code");
</script>
</head>
<body>
<select id="sel1" style="width:125px;height:35px;margin:10px 0 10px 0;">
</select>
</body>
</html>
Here's what the sheet named Options

Multiple sections in Handlebars template

I’m just getting to know Handlebars a bit better as a templating solution and have hit a problem that I don’t know how to solve.
I’ve added sections to my layout, one for the header and one for the footer for dynamically inserting scripts from my views. However, only the first section ever renders. The second one (regardless of order) is always omitted.
My layout is a simple HTML page:
<!doctype html>
<html>
<head>
<title>Test site</title>
{{{_sections.head}}}
</head>
<body>
<header>
//Logo and stuff here
</header>
{{{body}}}
<script src="//code.jquery.com/jquery-2.0.2.min.js"></script>
{{{_sections.footer}}}
</body>
</html>
And in my layout file I have:
{{#section 'head'}}
<script src="//cdnjs.cloudflare.com/ajax/libs/handlebars.js/1.3.0/handlebars.min.js"></script>
{{/section}}
//basic HTML here
{{#section 'footer'}}
<script>
alert("this doesn’t fire if its second!");
</script>
{{/section}}
The header section appears on the page but the footer does not. The thing is, if I put the footer at the top of the page (i.e. before the {{section ‘head’}} that then renders but the head section no longer renders.
In my app.js I’m setting up the section functionality as follows:
var handlebars = require('express3-handlebars')
.create({
defaultLayout: 'main',
helpers: {
section: function (name, options) {
if (!this._sections) {
this._sections = {};
this._sections[name] = options.fn(this);
return null;
}
}
}
});
app.engine('handlebars', handlebars.engine);
app.set('view engine', 'handlebars');
Any ideas what I’m doing wrong here or how to add support for both sections?
Thanks
I think your sections are overwriting each other. Try changing your handlebars create to the following:
var handlebars = require('express3-handlebars')
.create({
defaultLayout: 'main',
helpers: {
section: function (name, options) {
if (!this._sections) {
this._sections = {};
}
this._sections[name] = options.fn(this);
return null;
}
}
});

What needs to be changed in this code to make the page on top of it that loads this in a iframe change load a new url?

ok so heres my code
<html>
<head>
<title></title>
<body>
<script>
<!--
/*
Cookie Redirect. Written by PerlScriptsJavaScripts.com
Copyright http://www.perlscriptsjavascripts.com
Free and commercial Perl and JavaScripts
*/
// page to go to if cookie exists
go_to = "http://www.cookieisthere.com";
// number of days cookie lives for
num_days = 365;
function ged(noDays){
var today = new Date();
var expr = new Date(today.getTime() + noDays*24*60*60*1000);
return expr.toGMTString();
}
function readCookie(cookieName){
var start = document.cookie.indexOf(cookieName);
if (start == -1){
} else {
window.location = go_to;
}
}
readCookie("seenit");
// -->
</script>
</body>
</html>
This page will load on a page through a iframe... if the cookie is their i want the parent window to go to http://www.cookieisthere.com not the original page. After reading up on it a bit some people say use _top where the link is but i dont know how to do this. All help is much appreciated :)
Try this instead
<html>
<head>
<title></title>
<body>
<script>
<!--
/*
Cookie Redirect. Written by PerlScriptsJavaScripts.com
Copyright http://www.perlscriptsjavascripts.com
Free and commercial Perl and JavaScripts
*/
// page to go to if cookie exists
go_to = "http://www.cookieisthere.com";
// number of days cookie lives for
num_days = 365;
function ged(noDays){
var today = new Date();
var expr = new Date(today.getTime() + noDays*24*60*60*1000);
return expr.toGMTString();
}
function readCookie(cookieName){
var start = document.cookie.indexOf(cookieName);
if (start == -1){
} else {
window.top.location = go_to;
}
}
readCookie("seenit");
// -->
</script>
</body>
</html>

Resources