이 책은 지난번에 계속되고 있습니다. 우리는 40 페이지의 내용을 연속으로 기어 다니기 위해 프로그램을 수정해야합니다. 즉, 각 기사의 제목, 링크, 첫 번째 의견, 코멘트 사용자 및 포럼 포럼을 출력해야합니다.
그림에서 볼 수 있듯이 $('.reply_author').eq(0).text().trim(); 올바른 첫 번째 의견 사용자입니다.
{<1>}
EventProxy에서 주석 및 사용자 이름 컨텐츠를 얻은 후 사용자 지점을 계속 기어 다니기 위해 사용자 이름을 통해 사용자 인터페이스로 이동해야합니다.
코드 사본은 다음과 같습니다.
var $ = cheestio.load (topichtml);
//이 URL은 대상 URL을 크롤링하는 다음 단계입니다.
var userhref = 'https://cnodejs.org' + $ ( '. Reply_author'). eq (0) .attr ( 'href');
userhref = url.resolve (turl, userhref);
var title = $ ( '. topic_full_title'). text (). trim (). 교체 (// n/g, "") ;;
var href = topicurl;
var comment1 = $ ( '. Reply_Content'). eq (0) .text (). trim ();
var author1 = $ ( '. Reply_Author'). eq (0) .text (). trim ();
// 매개 변수를 다음 동시 크롤링으로 전달합니다
ep.emit ( 'user_html', [userhref, title, href, comment1, author1]);
이번에는 이벤트에서, 우리는 점수가 배치되는 위치를 찾고 싶습니다 (class = "big").
{<2>}
클래스 이름 만 찾아서 결과를 먼저 출력 해보자
코드 사본은 다음과 같습니다.
var 결과 = superagent.get (userurl)
.end (function (err, res) {
if (err) {
return console.error (err);
}
var $ = headeio.load (res.text);
var score = $ ( '. big'). text (). trim ();
Console.log (사용자 [1]);
Console.log (사용자 [2]);
Console.log (사용자 [3]);
Console.log (사용자 [4]);
console.log ($ ( '. big'). text (). trim ());
반품 ({
제목 : 사용자 [1],
HREF : 사용자 [2],
코멘트 1 : 사용자 [3],
저자 1 : 사용자 [4],
점수 1 : 점수
});
});
});
프로그램을 실행하면 결과 가이 코드에서 얻습니다.
{<3>}
그러나 문제는 .end ()의 콜백 함수에서 결과를 올바르게 출력 할 수 있지만 결과를 올바르게 출력 할 수 없다는 것입니다. 자세히 살펴보면 출력이 필요한 출력은 요청 객체입니다. 이것은 부주의 한 실수 때문입니다. .end () 함수는 리턴 값을 요청 객체로 전달하지 않으며 결과를 이전 레이어 (사용자)로 반환해야합니다.
코드 사본은 다음과 같습니다.
// userDetails를 찾습니다
ep.after ( 'user_html', topicurls.length, function (사용자) {
user = user.map (function (user) {
var userurl = user [0];
var 점수;
SuperAgent.get (userurl)
.end (function (err, res) {
if (err) {
return console.error (err);
}
//console.log(res.text);
var $ = headeio.load (res.text);
score = $ ( '. big'). text (). trim ();
});
반품 ({
제목 : 사용자 [1],
HREF : 사용자 [2],
코멘트 1 : 사용자 [3],
저자 1 : 사용자 [4],
점수 1 : 점수
});
});
수출 사용자를 잘 수출하고 score1 이외의 다른 것이 올바른 값임을 알 수 있습니다. 조심스럽게 디버깅을 한 후 프로그램이 먼저 Console.log ()를 수행 한 다음 .map ()를 수행 한 것을 발견했습니다. 보다 정확하게는 .map () 함수 내에서 .get () 콜백 함수는 할당 점수를 완료하지 못하고 반환 값이 수행됩니다. 이것은 비동기 콜백 함수이며 외부 동기화 작업은 콜백 기능이 작업을 완료 할 때까지 기다리지 않습니다.
{<4>}
내 접근 방식은 다른 메시지 계층을 방출하고 필요한 데이터를 메시지와 함께 수신 메시지 작업에 전달하는 것입니다. () 이후에 모든 메시지를 수신 할 때만 전달 된 매개 변수 (결과)를 인쇄합니다.
코드 사본은 다음과 같습니다.
score = $ ( '. big') text (). trim ();
// 새로 추가되었습니다
ep.emit ( 'got_score', [user [1], User [2], User [3], User [4], score]);
..... .....
ep.after ( 'got_score', 10, function (사용자) {
Console.log (사용자);
});
{<6>}
이 문제는 해결되었지만 score1의 값은 너무 큰 것 같습니다. 다시 한 번 살펴본 후에는 두 가지 클래스 = '큰'이 있으며 사용자의 주제 컬렉션은이 클래스에 속합니다. 우리는 Cheerio의 .slice (start, [end])를 통해 첫 번째 요소를 자르고 점수를 score = $ ( '. big')로 수정해야합니다. slice (0) .eq (0) .text (). trim ();. 올바른 결과는 그림에 나와 있습니다.
{<7>}