How to scrape a web page for the src of an image? - node.js

Basically I am trying to get the image src from a webpage so I can then download the image. Everything I have tried does not work.
Also, I am fairly new to node.js and cheerio, so bear with me.
var DilbertURL = 'http://Dilbert.com/strip/' + getDateTime();
request(DilbertURL, function (error, response, body) {
var $ = cheerio.load(body);
$('div.container-fluid').each(function(i, element){
var src = $('.img-responsive img-comic').attr("src");
console.log(src);
});
});
Everything I have tried to get the src of the dilbert image does not work. it all comes back 'undefined'. The html for the image goes like this...
<img alt="Wally's Passion - Dilbert by Scott Adams"
class="img-responsive img-comic" height="280" src="http://assets.amuniversal.com/dc0c4f80fd6e0132ef1a005056a9545d"
width="900">
What exactly am i doing wrong?

change this line to
var src = $('.img-responsive img-comic').attr("src");
this
var src = $('.img-responsive.img-comic').attr("src");
The selector will now work as intended! no space is needed to show that both classes belong to the same element rather than something with .img-responsive with a child element called img-comic which clearly wont exist!
Cheers

Related

How to create a url that opens a tab downloads a file and closes the tab

I want to create an URL that when clicked upon opens a tab, downloads a file, and closes that tab. Do you guys know how to do it?
Following is an example: https://cdn.discordapp.com/attachments/850262728428748830/937385812671209502/vineboom.ogg
I am quite new to this and overwhelmed to know where to start. Can somebody assist me with this?
I tried messing with Anchor tag but that is not the answer. According to my research figured it has something to do with NodeJS and ExpressJS. Still no idea of what to do.
Create require variables as shown and then created a function with whatever name you like, here I am using "onLoad" as the name. This function just checks for the file name in the URL's file parameter specified then tries to find it in the server.
var url_string = window.location; //window.location.href
var url = new URL(url_string);
var file = url.searchParams.get("file");
var dFile = file;
function onLoad() {
var hiddenElement = document.createElement('a');
hiddenElement.href = `${dFile}`;
hiddenElement.target = '_blank';
hiddenElement.download = `${dFile}`;
hiddenElement.click();
close()
}
Make sure to add onLoad function into the body with event listener of "onload"
<!DOCTYPE html>
<body onload="onLoad()">
</body>

Marko Dynamic Tag with Component

I have a marko website where I have some dynamic components being called via a for loop:
/pages/note/index.marko
import layout from "../../layouts/base"
<${layout} title="test">
<for|card| of=input.cards>
<${card} />
</for>
</>
this is given a set of "notes" (just other marko files with the content) that I want to fill the page with dynamically based on the request (this is handled in the server just fine). It is loading these notes fine.
However, when I have the card marko file use a component, the component ony half works.
note1/index.marko
<math>5x+1=11</math>
math/index.marko
class {
onCreate() {
console.log("CREATED") // runs
}
onMount() {
console.log("MOUNTED") // doesn't run
// eventually I plan to run some math rendering code here
}
}
<span><${input.renderBody} /></span>
The issue is that the browser side of things never run. Also, I am getting this inexplicable error in the browser
edit: changed the rendering in the routing. somehow the error went away
routes.js
...
app.get("/note.html", async (req, res, next) => {
let title = req.query.title || "" // get the requested card
let dependencies = request(`./notes/${title}/dependencies.json`) || [] // get all of the linked cards to the requested card
let cards = [title, ...dependencies].map(note => request(`./notes/${note}`)) // get the marko elements for each card
// by this point, "cards" is a list with marko templates from the /notes/ directory
// render
let page = request(`./pages/note`, next)
let out = page.render({"title": title, "cards": cards}, res)
}
...
My file structure is set up like this:
server.js
routes.js
pages/
note/
index.marko
notes/
note1/
index.marko
note2...
components/
math/
index.marko
layouts/
base/
index.marko
Using: node, express, marko, & lasso.
Your custom tag of <math> is colliding with the native MathML <math> element, which is why you’re getting that error only in the browser.
Try naming it something else, like <Math> or <my-math>.

Connect assets with handlebars?

The typical way to include the connect assets file is
!= css("main")
That is with .jade though. I am using handlebars and I have no clue how I can add the file?
I am using node-sass as well.
Just guessing, something like this works (see blog post):
var connectAssets = require("connect-assets")();
app.use(connectAssets);
var hbs = require('hbs');
hbs.registerHelper('css', function() {
var css = connectAssets.options.helperContext.css.apply(this, arguments);
return new hbs.SafeString(css);
});

Passing objects between nodejs and jade

I have the following code in my server.js
var cddata = [];
body.rows.forEach(function(doc) {
cddata.push([{id: doc.id, name: doc.key, text:doc.value.Time, group: 1}]);
});
response.render('timeline', {cddata: JSON.stringify(cddata)});
and I have the following in my Jade view file
script(src='vis/dist/vis.js')
link(rel="stylesheet", href="vis/dist/vis.css", type="text/css")
script.
//alert(cddata);
var options = {};
var data = new vis.DataSet(cddata);
var container = document.getElementById('visualization');
new vis.Timeline(container, data, options);
However, nothing related to the chart is rendered. I presume the object is not correctly passed to the jade file. Please help!
Also, is there a way to verify the incoming object in Jade? Alerts dont seem to work.
thanks
The <script> in your jade is a browser side script so won't be able to access variables in the templates generation scope. You'll need to output your data as JSON and read it in using browser side JavaScript, something like this:
script(src='vis/dist/vis.js')
link(rel="stylesheet", href="vis/dist/vis.css", type="text/css")
script.
var chartData = JSON.parse('#{cddata}')
var options = {};
var data = new vis.DataSet(chartData);
var container = document.getElementById('visualization');
new vis.Timeline(container, data, options);
After much deliberation, the following worked to pass object from node server to client side server scripting on Jade file.
on the server.js, where dbdata is an array of JSON objects
response.render('timeline', {dbdata:dbdata});
On the jade file,
script.
var chartData = !{JSON.stringify(dbdata)};
Thanks,

Retrieving HTML from CouchBase into Node.js / Express 4 leaves it unrendered

I'm having a small issue with rendering HTML, stored in CouchBase, fetched by Node.js
In CouchBase I have several small HTML-snippets. They contain text, tags such as <br /> and html entities such as <. They are of course stored as an escaped string in JSON.
So far, so good. However when I pull it out and display on the page, it is rendered "as-is", without being interpreted as HTML.
For example:
[ some content ...]
<p>Lorem is > ipsum<br />And another line</p>
[rest of content ...]
From the controller in Express 4:
var express = require('express');
var router = express.Router();
var couchbase = require('couchbase');
var cluster = new couchbase.Cluster('couchbase://myserver');
var bucket = cluster.openBucket('someBucket', 'somePassword');
var Entities = require('html-entities').XmlEntities;
entities = new Entities();
var utf8 = require('utf8');
/* GET home page. */
router.get('/', function(req, res) {
bucket.get('my:thingie:44', function(err, result) {
if(err) throw err
console.log(result);
var html = utf8.decode(entities.decode(result.value.thingie.html));
// var html = utf8.encode(result.value.thingie.html);
// var html = utf8.decode(result.value.thingie.html);
res.render('index', { title: 'PageTitle', content: html });
});
});
It is then passed to the template (using hogan.js) for rendering.
When looking into this I found that it might have something to do with the encoding of the <'s and <'s that prevent it from being parsed. You can see my converting attempts in the code, where none of the options gave the desired result, i.e. rendering the contents as HTML.
When using utf8.decode(), no difference.
Using utf8.encode(), no difference.
Using entities.decode() it convert < into < as predicted, but it's not rendered even if <div;&gt becomes <div>.
Any ideas?
I found the solution over here: Partials with Node.js + Express + Hogan.js
When putting HTML in a Hogan template, you have to use {{{var}}} instead of {{var}}.
And thus it renders beautifully, as intended :)
Wasn't encoding issues at all ;)

Resources