My project is a webscraper using axios, cheerio and express. Every time I try to run the project, it errors out.
I am using my friend's website for a test page. This is the code I used:
const express = require('express')
const app = express()
const port = 3000
const publicDir = app.use(express.static('public'))
var cheerio = require('cheerio'); // Basically jQuery for node.js
const { replaceWith } = require('cheerio/lib/api/manipulation');
const axios = require('axios').default;
app.get('/', (req, res) => {
res.render('/public/index.html')
})
app.get('/imagineoranges', (req, res) => {
const $ = cheerio.load('/imagineoranges')
axios.get("https://imagineoranges.neocities.org")
.then(({data}) => res.send(data))
.then( $('a:link').css("color: white;") )
.then( $('a:visited').css("color: yellow;") )
.then( $('a:hover').css("color: yellow;") )
.then( $("body").css("@import url('https://fonts.googleapis.com/css2?family=Rubik&display=swap'); background-color: #ff7300; color: white; font-family: 'Rubik', sans-serif;") )
})
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
The Result is:
node:internal/modules/cjs/loader:535
throw e;
^
Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './lib/api/manipulation' is not defined by "exports" in /home/lucas/Desktop/UBlock/node_modules/cheerio/package.json
at new NodeError (node:internal/errors:393:5)
at throwExportsNotFound (node:internal/modules/esm/resolve:292:9)
at packageExportsResolve (node:internal/modules/esm/resolve:602:3)
at resolveExports (node:internal/modules/cjs/loader:529:36)
at Module._findPath (node:internal/modules/cjs/loader:569:31)
at Module._resolveFilename (node:internal/modules/cjs/loader:981:27)
at Module._load (node:internal/modules/cjs/loader:841:27)
at Module.require (node:internal/modules/cjs/loader:1061:19)
at require (node:internal/modules/cjs/helpers:103:18)
at Object.<anonymous> (/home/lucas/Desktop/UBlock/index.js:6:25) {
code: 'ERR_PACKAGE_PATH_NOT_EXPORTED'
}
Node.js v19.0.1
CodePudding user response:
You should be providing the response HTML to Cheerio, manipulating the document and then rendering it to the response.
The styles you're trying to set look more like they should be done via CSS so consider inserting a <style>
tag.
For example
app.get("/imagineoranges", async (req, res) => {
try {
const { data } = await axios.get("https://imagineoranges.neocities.org", {
responseType: "text",
});
const $ = cheerio.load(data);
$("head").append(
`<style type="text/css">@import url(https://fonts.googleapis.com/css2?family=Rubik&display=swap);a:link,body{color:#fff}a:hover,a:visited{color:#ff0}body{background-color:#ff7300;font-family:Rubik,sans-serif}<style>`
);
res.set("content-type", "text/html").send($.root().html());
} catch (err) {
res.status(err.response?.status ?? 500).send(err.response?.data);
}
});