Le livre se poursuit la dernière fois, nous devons modifier le programme pour ramper le contenu de 40 pages d'affilée. C'est-à-dire que nous devons sortir le titre, le lien, le premier commentaire, les points utilisateur et le forum de commentaires de chaque article.
Comme le montre la figure, la valeur obtenue $('.reply_author').eq(0).text().trim(); est le bon utilisateur de premier commentaire.
{<1>}
Après avoir obtenu des commentaires et du contenu du nom d'utilisateur dans EventProxy, nous devons passer à l'interface utilisateur via le nom d'utilisateur pour continuer à ramper les points utilisateur
La copie de code est la suivante:
var $ = cheeseio.load (topichtml);
// Cette URL est la prochaine étape pour ramper l'URL cible
var userHref = 'https://cnodejs.org' + $ ('. Répondre_author'). eq (0) .attr ('href');
userHref = url.Resolve (turl, userHref);
var title = $ ('. topic_full_title'). text (). Trim (). Remplace (// n / g, "") ;;
var href = topicurl;
var comment1 = $ ('. Répondre_content'). Eq (0) .Text (). Trim ();
var auteur1 = $ ('. Répondre_author'). Eq (0) .Text (). Trim ();
// Passez les paramètres à la crawl concurrent suivant
ep.emit ('user_html', [userHref, title, href, comment1, auteur1]);
Dans EventProxy cette fois, nous voulons trouver où le score est placé (class = "big").
{<2>}
Trouvez simplement le nom de classe, essayons d'abord de sortir le résultat
La copie de code est la suivante:
var résultat = superagent.get (userUrl)
.end (fonction (err, res) {
if (err) {
return console.error (err);
}
var $ = cheeseio.load (res.text);
var score = $ ('. big'). text (). Trim ();
console.log (utilisateur [1]);
console.log (utilisateur [2]);
console.log (utilisateur [3]);
console.log (utilisateur [4]);
Console.log ($ ('. Big'). Text (). Trim ());
retour ({
Titre: utilisateur [1],
HREF: utilisateur [2],
comment1: utilisateur [3],
Auteur1: utilisateur [4],
score1: score
});
});
});
Exécutez le programme et le résultat est obtenu par ce code.
{<3>}
Mais le problème est que nous pouvons sortir correctement le résultat dans la fonction de rappel de .end (), mais nous ne pouvons pas sortir correctement le résultat. Si vous regardez attentivement, la sortie qui doit être la sortie est un objet de demande. C'est à cause des erreurs imprudentes. La fonction .end () ne transmet pas la valeur de retour à l'objet de demande et doit renvoyer le résultat à la couche précédente (utilisateurs).
La copie de code est la suivante:
// Trouver UserDetails
ep.after ('user_html', topicurls.length, fonction (utilisateurs) {
users = users.map (fonction (utilisateur) {
var userUrl = user [0];
Score VAR;
superagent.get (userurl)
.end (fonction (err, res) {
if (err) {
return console.error (err);
}
//console.log(res.Text);
var $ = cheeseio.load (res.text);
score = $ ('. big'). text (). Trim ();
});
retour ({
Titre: utilisateur [1],
HREF: utilisateur [2],
comment1: utilisateur [3],
Auteur1: utilisateur [4],
score1: score
});
});
Exportez bien les utilisateurs et constatez qu'autrement que Score1 sont les valeurs correctes. Après un débogage minutieux, j'ai constaté que le programme exécutait d'abord Console.log () puis exécuté .map (). Plus précisément, dans la fonction .map (), la fonction de rappel .get () ne termine pas le score d'attribution et la valeur de retour de retour est effectuée. Il s'agit de la fonction de rappel asynchrone, et l'opération synchrone externe n'attendra pas que la fonction de rappel terminera l'opération.
{<4>}
Mon approche consiste à émettre une autre couche de message et à transmettre les données requises à l'opération de message de réception avec le message. Après (), ce n'est que lorsque tous les messages sont reçus seront imprimés les paramètres passés (résultat).
La copie de code est la suivante:
score = $ ('. big') text (). Trim ();
// nouvellement ajouté
ep.emit ('got_score', [utilisateur [1], utilisateur [2], utilisateur [3], utilisateur [4], score]);
.....
ep.after ('got_score', 10, fonction (utilisateurs) {
console.log (utilisateurs);
});
{<6>}
Ce problème a été résolu, mais la valeur de Score1 semble être trop grande. Après avoir regardé à nouveau, il s'avère qu'il y a deux classes = 'Big', et la collection de sujets de l'utilisateur appartient également à cette classe. Nous devons couper le premier élément via le .slice de Cheerio (start, [fin]) et modifier le score pour score = $ ('. Big'). Slice (0) .eq (0) .Text (). Trim ();. Le résultat correct est illustré sur la figure.
{<7>}