Estoy tratando de crear un raspador web html y enviar por correo electrónico el contenido de lo que se encontró.
Estoy trabajando con un sitio de música y estoy pasando los nombres de los artistas a través de la línea de comando, que luego debería acceder al sitio web, buscando las etiquetas html de las entradas de canciones en las listas. El correo electrónico enviado debe ser la lista de canciones de ese artista en particular o cualquier canción en la que aparezcan, de las primeras 25 canciones en el sitio.
Sin embargo, mi código solo envía correos electrónicos y salidas cuando se pasa un argumento, pero cuando se ingresan más de uno, los contenidos no se muestran en el correo electrónico:
Aquí hay un fragmento de mi código/bucle jquery:
var request = require('request'); var cheerio = require('cheerio'); var nodemailer = require('nodemailer'); var process = require('process'); var artists = process.argv.slice(2).toString(); var creds= require('./credentials.json'); var transporter = nodemailer.createTransport(creds); request('http://www.popvortex.com/music/charts/top-rap-songs.php', function (error, response, html) { if (!error && response.statusCode == 200) { var $ = cheerio.load(html); var data=""; //var artist= $(this).children('em.artist').text(); //var song = $(this).children('cite.title').text(); $('p.title-artist').each(function(i, element) { var artist= $(this).children('em.artist').text(); var song = $(this).children('cite.title').text(); if(i<25 && (artist.includes(artists) || song.includes(artists))) { var artist= $(this).children('em.artist').text(); var song = $(this).children('cite.title').text(); data+=artist + ' : ' + song; console.log(artist + ' : '+ song); } }) var mailOptions = { from: creds.user, to : 'jguffer4234@gmail.com', subject: 'Your artists are: ' + artists.toString(), text: data, }entrada/salida de línea de comando
El correo electrónico todavía se envía cuando se ingresa más de un artista pero las canciones en las que están incluidos no lo están.
Correo electrónico de Latto Jack, sin cuerpo con todas sus canciones
¿Alguien puede ayudar? Y la ayuda con mi formato del correo electrónico (línea por línea) también sería útil.
Creo que el problema está en esta línea:
if(i<25 && (artist.includes(artists) || song.includes(artists))) { Creo que el uso del método includes de la cadena es incorrecto.
En su lugar, intente con:
if(i<25 && (artists.includes(artist) || artists.includes(song))) {Basado en la documentación , creé un ejemplo para mostrar cómo funciona:
let list = ["a", "b", "c"]; console.log("Case 1: ", "a".includes(list)); // false console.log("Case 2: ", list.includes("a")); // trueSi bien no estoy seguro de si esto resolverá todo el problema que está teniendo, espero que lo ayude al menos en eso.
Está bien. Como prometí, aquí hay una solución alternativa.
Dado que el paquete de request está en desuso, estoy usando axios en su lugar.
Tenga en cuenta que rompí el problema en pedazos pequeños.
Esto me permitió proporcionar nombres que describen lo que se está haciendo, lo hace más fácil de leer y además me permite probar cada parte a medida que codifico.
En el package.json , lo hice:
{ "name": "experiment1", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "start": "node index.js", "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "axios": "^0.27.2", "cheerio": "^1.0.0-rc.10" } }La línea de comando que estoy usando, por ejemplo, es:
~/Experiment1$ npm start "Jack Harlow" "Big Energy"Los resultados son:
> experiment1@1.0.0 start > node index.js "Jack Harlow" "Big Energy" data: { 'Jack Harlow': 'First Class', 'Latto & Mariah Carey': 'Big Energy (Remix) [feat. DJ Khaled]', Latto: 'Big Energy', 'Lil Nas X & Jack Harlow': 'INDUSTRY BABY' }Nota: Tenga en cuenta que los duplicados no están incluidos.
Aquí está el código:
const axios = require('axios').default; const url = 'http://www.popvortex.com/music/charts/top-rap-songs.php'; axios.get(url) .then((response) => { let data = findArtistAndSong(response.data); console.log("data:", data); }) .catch((error) => { console.error(error); }); const cheerio = require('cheerio'); const LIST_LIMIT = 25; function findArtistAndSong(html){ const $ = cheerio.load(html); const data = {}; $('p.title-artist').each(function(i, element) { let artist= $(this).children('em.artist').text(); let song = $(this).children('cite.title').text(); if (i < LIST_LIMIT && doesArtistOrSongMatch(artist, song)) { data[artist] = song; } }); return data; } function doesArtistOrSongMatch(artist, song){ return isMatch(artist) || isMatch(song); } const arguments = process.argv.slice(2); const isMatch = (search) => { return arguments.some(item => search.includes(item)); };Por favor hazme saber si tienes preguntas.