рд╡реЗрдм
рдХреНрд░реЙрд▓рд░ (рдпрд╛ рд╡реЗрдм рд╕реНрдкрд╛рдЗрдбрд░) рд╡реЗрдм рдкреЗрдЬреЛрдВ рдХреЛ рдХреНрд░реЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЦреЛрдЬ рдЗрдВрдЬрди рдХрд╛ рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ, рддрд╛рдХрд┐ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЙрдирдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рджрд░реНрдЬ рдХреА рдЬрд╛ рд╕рдХреЗ, рдореБрдЦреНрдпрддрдГ рдЙрдирдХреЗ рдЖрдЧреЗ рдХреЗ рдЕрдиреБрдХреНрд░рдордг рдХреЗ рд▓рд┐рдПред рдЦреЛрдЬ рдЗрдВрдЬрди (Google, рдпреИрдВрдбреЗрдХреНрд╕, рдмрд┐рдВрдЧ), рд╕рд╛рде рд╣реА рд╕рд╛рде рдПрд╕рдИрдУ рдЙрддреНрдкрд╛рдж (SEMrush, MOZ, ahrefs) рдФрд░ рди рдХреЗрд╡рд▓ рдРрд╕реА рдЪреАрдЬ рд╣реИред рдФрд░ рдпрд╣ рдмрд╛рдд рдХрд╛рдлреА рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ: рджреЛрдиреЛрдВ рд╕рдВрднрд╛рд╡рд┐рдд рдФрд░ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЛрдВ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдФрд░ рддрдХрдиреАрдХреА рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдПред

рдЗрд╕ рд▓реЗрдЦ рдХреЗ рд╕рд╛рде, рд╣рдо рдЖрдкрдХреА рдХреНрд░реЙрд▓рд░
рдмрд╛рдЗрдХ рдмрдирд╛рдирд╛ рд╢реБрд░реВ рдХрд░ рджреЗрдВрдЧреЗ, рдХрдИ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░реЗрдВрдЧреЗ рдФрд░ рдиреБрдХрд╕рд╛рди рдХреА рдмреИрдардХ рдХрд░реЗрдВрдЧреЗред рдПрдХ рд╕рд░рд▓ рдкреБрдирд░рд╛рд╡рд░реНрддреА рд╕рдорд╛рд░реЛрд╣ рд╕реЗ рдПрдХ рд╕реНрдХреЗрд▓реЗрдмрд▓ рдФрд░ рдПрдХреНрд╕реНрдЯреЗрдВрд╕рд┐рдмрд▓ рд╕реЗрд╡рд╛ рдХреЗ рд▓рд┐рдПред рджрд┐рд▓рдЪрд╕реНрдк рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП!
рдкрд░рд┐рдЪрдп
Iteratively - рдЗрд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рд░рд┐рд▓реАрдЬрд╝ рдХреЗ рдЕрдВрдд рдореЗрдВ "рдЙрддреНрдкрд╛рдж" рдХрд╛ рддреИрдпрд╛рд░-рд╕реЗ-рдЙрдкрдпреЛрдЧ рд╕рдВрд╕реНрдХрд░рдг рд╕рд╣рдордд рд╕реАрдорд╛рдУрдВ, рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдФрд░ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рд╕рд╛рде рдЕрдкреЗрдХреНрд╖рд┐рдд рд╣реИред
Node.js рдФрд░
рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдордВрдЪ рдФрд░ рднрд╛рд╖рд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдЪреБрдирд╛ рдЧрдпрд╛ рдерд╛, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╕рд░рд▓ рдФрд░ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд╣реИред рдмреЗрд╢рдХ, рдФрджреНрдпреЛрдЧрд┐рдХ рд╡рд┐рдХрд╛рд╕ рдХреЗ рд▓рд┐рдП, рддрдХрдиреАрдХреА рдЖрдзрд╛рд░ рдХрд╛ рд╡рд┐рдХрд▓реНрдк рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ, рдЕрдкреЗрдХреНрд╖рд╛рдУрдВ рдФрд░ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдкреНрд░рджрд░реНрд╢рди рдФрд░ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдХреЗ рд░реВрдк рдореЗрдВ, рдпрд╣ рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдХреБрдЫ рднреА рдирд╣реАрдВ рд╣реИ (IMHO)ред
рдпрд╣ рдореЗрд░рд╛ рдХреНрд░реЙрд▓рд░ рд╣реИред рдРрд╕реЗ рдХрдИ рдХреНрд░реЙрд▓рд░ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдПрдХ рдореЗрд░рд╛ рд╣реИред
рдореЗрд░рд╛ рдХреНрд░реЙрд▓рд░ рдореЗрд░рд╛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рджреЛрд╕реНрдд рд╣реИред
рдХреНрд░реЙрд▓рд░ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдПрдХ рдХрд╛рдлреА рд▓реЛрдХрдкреНрд░рд┐рдп рдХрд╛рд░реНрдп рд╣реИ рдФрд░ рддрдХрдиреАрдХреА рд╕рд╛рдХреНрд╖рд╛рддреНрдХрд╛рд░ рдореЗрдВ рднреА рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдмрд╣реБрдд рд╕рд╛рд░реА
рддреИрдпрд╛рд░рд┐рдпрд╛рдВ (
рдЕрдкрд╛рдЪреЗ рдирдЪ ) рдФрд░ рд╡рд┐рднрд┐рдиреНрди рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдФрд░ рдХрдИ рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рд╕реНрд╡-рд▓рд┐рдЦрд┐рдд рд╕рдорд╛рдзрд╛рди рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рд╡рд┐рдХрд╛рд╕ рдпрд╛ рдЙрдкрдпреЛрдЧ рдореЗрдВ рд╡реНрдпрдХреНрддрд┐рдЧрдд рдЕрдиреБрднрд╡ рд╕реЗ рдХрд┐рд╕реА рднреА рдЯрд┐рдкреНрдкрдгреА рдХрд╛ рд╕реНрд╡рд╛рдЧрдд рд╣реИ рдФрд░ рджрд┐рд▓рдЪрд╕реНрдк рд╣реЛрдЧрд╛ред
рд╕рдорд╕реНрдпрд╛ рдХрд╛ рдмрдпрд╛рди
рд╣рдорд╛рд░реЗ
рдЯреИрдп-рдмреНрд▓реЙрдкрд░ рдХреНрд░реЙрд▓рд░ рдХреЗ рдкрд╣рд▓реЗ (рдкреНрд░рд╛рд░рдВрднрд┐рдХ) рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдп рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реЛрдЧрд╛:
рдПрдХ-рджреЛ рдХреНрд░реЙрд▓рд░ 1.0
рдПрдХ рдХреНрд░реЙрд▓рд░ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд▓рд┐рдЦреЗрдВ рдЬреЛ рдПрдХ рдЫреЛрдЯреА (100 рдкреГрд╖реНрдареЛрдВ рддрдХ) рд╕рд╛рдЗрдЯ рдХреЗ рдЖрдВрддрд░рд┐рдХ <a href /> рд▓рд┐рдВрдХ рдХреЛ рдмрд╛рдпрдкрд╛рд╕ рдХрд░рддреА рд╣реИред рдирддреАрдЬрддрди, рдкреНрд░рд╛рдкреНрдд рдХреЛрдб рдФрд░ рдЙрдирдХреЗ рд▓рд┐рдВрдХрд┐рдВрдЧ рдХреЗ рдирдХреНрд╢реЗ рдХреЗ рд╕рд╛рде рдкреГрд╖реНрдареЛрдВ рдХреЗ URL рдХреА рдПрдХ рд╕реВрдЪреА рдкреНрд░рджрд╛рди рдХрд░реЗрдВред Robots.txt рдирд┐рдпрдо рдФрд░ rel = nofollow рд▓рд┐рдВрдХ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдЪреЗрддрд╛рд╡рдиреА! Robot.txt рдирд┐рдпрдореЛрдВ рдХреА рдЕрдирджреЗрдЦреА рд╕реНрдкрд╖реНрдЯ рдХрд╛рд░рдгреЛрдВ рд╕реЗ рдПрдХ рдмреБрд░рд╛ рд╡рд┐рдЪрд╛рд░ рд╣реИред рд╣рдо рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдЗрд╕ рдЪреВрдХ рдХреЗ рд▓рд┐рдП рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВрдЧреЗред рдЗрд╕ рдмреАрдЪ, рдкреГрд╖реНрдареЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рд╕реАрдорд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рд╕реАрдорд╛ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рдХреНрд░реЙрд▓ рдХрд░реЗрдВ рддрд╛рдХрд┐ рд╡рд╣ DoS рдХреЛ рди рд░реЛрдХреЗ рдФрд░ рдкреНрд░рд╛рдпреЛрдЧрд┐рдХ рд╕рд╛рдЗрдЯ рдХреЛ рдЖрдЬрд╝рдорд╛рдПрдВ (рдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рдирд┐рдЬреА "рд╣рдореНрд╕рдЯрд░ рд╕рд╛рдЗрдЯ" рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдмреЗрд╣рддрд░ рд╣реИ)ред
рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди
рдЕрдзреАрд░ рдХреЗ рд▓рд┐рдП,
рдпрд╣рд╛рдБ рдЗрд╕ рд╕рдорд╛рдзрд╛рди
рдХреЗ рд╕реНрд░реЛрдд рд╣реИрдВред
- HTTP (S) рдХреНрд▓рд╛рдЗрдВрдЯ
- рдЙрддреНрддрд░ рдХреЗ рд╡рд┐рдХрд▓реНрдк
- рд▓рд┐рдВрдХ рдирд┐рдХрд╛рд▓рдирд╛
- рд▓рд┐рдВрдХ рддреИрдпрд╛рд░реА рдФрд░ рдлрд╝рд┐рд▓реНрдЯрд░рд┐рдВрдЧ
- URL рд╕рд╛рдорд╛рдиреНрдпреАрдХрд░рдг
- рдореБрдЦреНрдп рд╕рдорд╛рд░реЛрд╣ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо
- рд╡рд╛рдкрд╕реА рдХрд╛ рдкрд░рд┐рдгрд╛рдо
1. HTTP (рдПрд╕) рдХреНрд▓рд╛рдЗрдВрдЯ
рдкрд╣рд▓реА рдЪреАрдЬ рдЬреЛ рд╣рдореЗрдВ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рд╡рд╣ рд╣реИ, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдЕрдиреБрд░реЛрдз рднреЗрдЬрдирд╛ рдФрд░ HTTP рдФрд░ HTTPS рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рдПрдВ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ред Node.js рдореЗрдВ рдЗрд╕рдХреЗ рд▓рд┐рдП рджреЛ рдореИрдЪрд┐рдВрдЧ рдХреНрд▓рд╛рдЗрдВрдЯ рд╣реИрдВред рдмреЗрд╢рдХ, рдЖрдк рдПрдХ
рддреИрдпрд╛рд░ рдЧреНрд░рд╛рд╣рдХ рдЕрдиреБрд░реЛрдз рд▓реЗ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╣рдорд╛рд░реЗ рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдП рдпрд╣ рдмреЗрд╣рдж рдмреЗрдорд╛рдиреА рд╣реИ: рд╣рдореЗрдВ рдмрд╕ рдПрдХ GET рдЕрдиреБрд░реЛрдз рднреЗрдЬрдиреЗ рдФрд░ рд╢рд░реАрд░ рдФрд░ рд╣реЗрдбрд░ рдХреЗ рд╕рд╛рде рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рджреЛрдиреЛрдВ рдХреНрд▓рд╛рдЗрдВрдЯреЛрдВ рдХрд╛ рдПрдкреАрдЖрдИ рдПрдХ рдЬреИрд╕рд╛ рд╣реИ, рд╣рдо рдПрдХ рдирдХреНрд╢рд╛ рдмрдирд╛рдПрдВрдЧреЗ:
const clients = { 'http:': require('http'), 'https:': require('https') };
рд╣рдо рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдлрдВрдХреНрд╢рди
рд▓рд╛рдиреЗ рдХреА рдШреЛрд╖рдгрд╛ рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХрд╛ рдПрдХрдорд╛рддреНрд░ рдкреИрд░рд╛рдореАрдЯрд░ рд╡рд╛рдВрдЫрд┐рдд рд╡реЗрдм рд╕рдВрд╕рд╛рдзрди рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХрд╛
рдкреВрд░реНрдг URL рд╣реЛрдЧрд╛ред
Url рдореЙрдбреНрдпреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ
, рд╣рдо рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЛ URL рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдкрд╛рд░реНрд╕ рдХрд░реЗрдВрдЧреЗред рдЗрд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЗ рд╕рд╛рде рдПрдХ рдлрд╝реАрд▓реНрдб рд╣реИ (рдПрдХ рдмреГрд╣рджрд╛рдиреНрддреНрд░ рдХреЗ рд╕рд╛рде), рдЬрд┐рд╕рдХреЗ рджреНрд╡рд╛рд░рд╛ рд╣рдо рдЙрдЪрд┐рдд рдЧреНрд░рд╛рд╣рдХ рдХрд╛ рдЪрдпрди рдХрд░реЗрдВрдЧреЗ:
const url = require('url'); function fetch(dst) { let dstURL = new URL(dst); let client = clients[dstURL.protocol]; if (!client) { throw new Error('Could not select a client for ' + dstURL.protocol); }
рдЕрдЧрд▓рд╛, рдЪрдпрдирд┐рдд рдЧреНрд░рд╛рд╣рдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ рдФрд░ рдПрдХ рд╡рд╛рджреЗ рдореЗрдВ
рд▓рд╛рдиреЗ рдХреЗ
рд▓рд┐рдП рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд▓рдкреЗрдЯреЗрдВ:
function fetch(dst) { return new Promise((resolve, reject) => {
рдЕрдм рд╣рдо рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рд░реВрдк рд╕реЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЕрднреА рд╣рдо рдЗрд╕рдХреЗ рд╕рд╛рде рдХреБрдЫ рдирд╣реАрдВ рдХрд░ рд░рд╣реЗ рд╣реИрдВред
2. рдЙрддреНрддрд░ рд╡рд┐рдХрд▓реНрдк
рд╕рд╛рдЗрдЯ рдХреЛ рдХреНрд░реЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, 3 рдЙрддреНрддрд░ рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдирд╛ рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ:
- рдареАрдХ рд╣реИ - рдПрдХ 2xx рд╕реНрдерд┐рддрд┐ рдХреЛрдб рдкреНрд░рд╛рдкреНрдд рд╣реБрдЖ рдерд╛ред рдЖрдЧреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╢рд░реАрд░ рдХреЛ рдмрдЪрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИ - рдирдП рд▓рд┐рдВрдХ рдирд┐рдХрд╛рд▓рдиреЗред
- REDIRECT - рдПрдХ 3xx рд╕реНрдерд┐рддрд┐ рдХреЛрдб рдкреНрд░рд╛рдкреНрдд рд╣реБрдЖ рдерд╛ред рдпрд╣ рджреВрд╕рд░реЗ рдкреГрд╖реНрда рдкрд░ рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рд┐рдд рд╣реИред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдореЗрдВ рд╕реНрдерд╛рди рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╢реАрд░реНрд╖рд▓реЗрдЦ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рдЬрд╣рд╛рдВ рд╕реЗ рд╣рдо рдПрдХ рдПрдХрд▓ "рдЖрдЙрдЯрдЧреЛрдЗрдВрдЧ" рд▓рд┐рдВрдХ рд▓реЗрдВрдЧреЗред
- NO_DATA - рдЕрдиреНрдп рд╕рднреА рдорд╛рдорд▓реЗ: рд╕реНрдерд╛рди рд╣реЗрдбрд░ рдХреЗ рдмрд┐рдирд╛ 4xx / 5xx рдФрд░ 3xxред рд╣рдорд╛рд░реЗ рдХреНрд░реЙрд▓рд░ рдХреЗ рдЖрдЧреЗ рдЬрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣реАрдВ рдирд╣реАрдВ рд╣реИред
рдЗрд╕рдХреА рдХрд╛рд░реНрдпрдкреНрд░рдгрд╛рд▓реА рдХреЛ рджрд░реНрд╢рд╛рддреЗ рд╣реБрдП рдкреНрд░реЛрд╕реИрд╕ рд░рд┐рд╕реНрдкрд╛рдВрд╕ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдПрдЧрд╛:
const ft = { 'OK': 1,
рдпрджрд┐-рдФрд░ рдХреА рд╕рд░реНрд╡реЛрддреНрддрдо рдкрд░рдВрдкрд░рд╛рдУрдВ рдореЗрдВ рдкрд░рд┐рдгрд╛рдо рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреА рд░рдгрдиреАрддрд┐ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди:
let code = res.statusCode; let codeGroup = Math.floor(code / 100);
рд╕рдВрдкреВрд░реНрдг рдлрд╝рдВрдХреНрд╢рди рдХреЛрдб :
рднреНрд░реВрдг рдлрд╝рдВрдХреНрд╢рди рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИред
3. рд▓рд┐рдВрдХ рдХрд╛ рдирд┐рд╖реНрдХрд░реНрд╖рдг
рдЕрдм, рдкреНрд░рд╛рдкреНрдд рдЙрддреНрддрд░ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдЖрдкрдХреЛ рдЖрдЧреЗ рдХреНрд░реЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
рднреНрд░реВрдг рдХреЗ рдкрд░рд┐рдгрд╛рдо рдбреЗрдЯрд╛ рд╕реЗ рд▓рд┐рдВрдХ рдирд┐рдХрд╛рд▓рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо
рдПрдХреНрд╕реНрдЯреНрд░реЗрдХреНрдЯ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рдкрд░рд┐рдгрд╛рдо рд╡рд╕реНрддреБ рдХреЛ рдЗрдирдкреБрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рд▓реЗрддрд╛ рд╣реИ рдФрд░ рдирдП рд▓рд┐рдВрдХ рдХреА рдПрдХ рд╕рд░рдгреА рджреЗрддрд╛ рд╣реИред
рдпрджрд┐ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рдХрд╛рд░ REDIRECT рд╣реИ, рддреЛ рдлрд╝рдВрдХреНрд╢рди
рд╕реНрдерд╛рди рдлрд╝реАрд▓реНрдб рд╕реЗ рдПрдХ рдПрдХрд▓ рд╕рдВрджрд░реНрдн рдХреЗ рд╕рд╛рде рдПрдХ рд╕рд░рдгреА рд▓реМрдЯрд╛рдПрдЧрд╛ред NO_DATA, рддреЛ рдПрдХ рдЦрд╛рд▓реА рд╕рд░рдгреАред рдпрджрд┐ рдареАрдХ рд╣реИ, рддреЛ рд╣рдореЗрдВ рдЦреЛрдЬ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╕реНрддреБрдд рдкрд╛рда
рд╕рд╛рдордЧреНрд░реА рдХреЗ рд▓рд┐рдП рдкрд╛рд░реНрд╕рд░ рдХреЛ рдХрдиреЗрдХреНрдЯ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред
<a href /> рдЦреЛрдЬ рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдП
, рдЖрдк рдПрдХ рдирд┐рдпрдорд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рднреА рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдпрд╣ рд╕рдорд╛рдзрд╛рди рдмрд┐рд▓реНрдХреБрд▓ рдкреИрдорд╛рдиреЗ рдкрд░ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рд╣рдо рдХрдо рд╕реЗ рдХрдо рд▓рд┐рдВрдХ рдХреЗ рдЕрдиреНрдп рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ (
рд░рд┐рд▓реЗ ) рдкрд░ рдзреНрдпрд╛рди рджреЗрдВрдЧреЗ, рдЕрдзрд┐рдХрддрдо рдХреЗ рд░реВрдк рдореЗрдВ, рд╣рдо
img ,
рд▓рд┐рдВрдХ ,
рд╕реНрдХреНрд░рд┐рдкреНрдЯ ,
рдСрдбрд┐рдпреЛ / рд╡реАрдбрд┐рдпреЛ (
рд╕реНрд░реЛрдд ) рдФрд░ рдЕрдиреНрдп рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪреЗрдВрдЧреЗред рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдХреЗ рдкрд╛рда рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдирд╛ рдФрд░ рд╕рд╛рдорд╛рдиреНрдп рдЪрдпрдирдХрд░реНрддрд╛рдУрдВ рдХреЛ рджрд░рдХрд┐рдирд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕рдХреЗ рдиреЛрдбреНрд╕ рдХрд╛ рдПрдХ рдкреЗрдбрд╝ рдмрдирд╛рдирд╛ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдЖрд╢рд╛рдЬрдирдХ рдФрд░ рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИред
рд╣рдо
рдиреЛрдб рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд▓реЛрдХрдкреНрд░рд┐рдп
JSDOM рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред
const { JSDOM } = require('jsdom'); let document = new JSDOM(fetched.content).window.document; let elements = document.getElementsByTagName('A'); return Array.from(elements) .map(el => el.getAttribute('href')) .filter(href => typeof href === 'string') .map(href => href.trim()) .filter(Boolean);
рд╣рдо рд╕рднреА
рдП рддрддреНрд╡реЛрдВ рдХреЛ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░
href рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рд╕рднреА рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд┐рдП рдЧрдП рдорд╛рди, рдпрджрд┐ рдЦрд╛рд▓реА рд▓рд╛рдЗрдиреЗрдВ рдирд╣реАрдВ рд╣реИрдВред
4. рд▓рд┐рдВрдХ рдХреА рддреИрдпрд╛рд░реА рдФрд░ рдлрд╝рд┐рд▓реНрдЯрд░рд┐рдВрдЧ
рдЪрд┐рдордЯрд╛ рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд▓рд┐рдВрдХ (URL) рдФрд░ рджреЛ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХрд╛ рдПрдХ рд╕реЗрдЯ рд╣реИ: 1) URL рд╕рд╛рдкреЗрдХреНрд╖ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ 2) URL рдмрд╛рд╣рд░реА рд╕рдВрд╕рд╛рдзрди рдХрд╛ рдиреЗрддреГрддреНрд╡ рдХрд░ рд╕рдХрддрд╛ рд╣реИ (рд╣рдореЗрдВ рдХреЗрд╡рд▓ рдЖрдВрддрд░рд┐рдХ рд▓реЛрдЧреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ)ред
рдкрд╣рд▓реА рд╕рдорд╕реНрдпрд╛ рдХреЛ
url.resolve рдлрд╝рдВрдХреНрд╢рди рджреНрд╡рд╛рд░рд╛ рдорджрдж рдХреА
рдЬрд╛рдПрдЧреА , рдЬреЛ рд╕реНрд░реЛрдд рдкреГрд╖реНрда рдХреЗ URL рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рд▓реИрдВрдбрд┐рдВрдЧ рдкреГрд╖реНрда рдХрд╛ URL рд╣рд▓ рдХрд░рддрд╛ рд╣реИред
рджреВрд╕рд░реА рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдпреВрдЯрд┐рд▓рд┐рдЯреА рдлрдВрдХреНрд╢рди
рдЗрдирд╕реНрдХреЛрдк рд▓рд┐рдЦрддреЗ рд╣реИрдВ рдЬреЛ рд╡рд░реНрддрдорд╛рди рдХреНрд░реЙрд▓ рдХреЗ рдмреЗрд╕ рдпреВрдЖрд░рдПрд▓ рдХреЗ рд╣реЛрд╕реНрдЯ рдХреЗ рдЦрд┐рд▓рд╛рдл рд▓реИрдВрдбрд┐рдВрдЧ рдкреЗрдЬ рдХреЗ рд╣реЛрд╕реНрдЯ рдХреА рдЬрд╛рдВрдЪ рдХрд░рддрд╛ рд╣реИ:
function getLowerHost(dst) { return (new URL(dst)).hostname.toLowerCase(); } function inScope(dst, base) { let dstHost = getLowerHost(dst); let baseHost = getLowerHost(base); let i = dstHost.indexOf(baseHost);
рдпрджрд┐ рдлрд╝рдВрдХреНрд╢рди рдкрд╛рдпрд╛ рдЧрдпрд╛ рдерд╛, рддреЛ рдлрд╝рдВрдХреНрд╢рди рдкрд┐рдЫрд▓реЗ рдЕрдХреНрд╖рд░ рдХреЗ рд▓рд┐рдП рдЪреЗрдХ рдХреЗ рд╕рд╛рде рд╕рдмрд╕реНрдЯреНрд░рд┐рдВрдЧ (
рдмреЗрд╕рд╣реЙрд╕реНрдЯ ) рдХреА рдЦреЛрдЬ рдХрд░рддрд╛ рд╣реИ: рдЪреВрдВрдХрд┐
wwwexample.com рдФрд░
example.com рдЕрд▓рдЧ-рдЕрд▓рдЧ рдбреЛрдореЗрди рд╣реИрдВред рдирддреАрдЬрддрди, рд╣рдо рджрд┐рдП рдЧрдП рдбреЛрдореЗрди рдХреЛ рдирд╣реАрдВ рдЫреЛрдбрд╝рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рдЙрдк рдбреЛрдореЗрди рдХреЛ рдмрд╛рдпрдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред
рд╣рдо "рдирд┐рд░рдкреЗрдХреНрд╖рддрд╛" рдЬреЛрдбрд╝рдХрд░ рдФрд░ рдЗрд╕рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рд▓рд┐рдВрдХ рдХреЛ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд░рдХреЗ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкрд░рд┐рд╖реНрдХреГрдд рдХрд░рддреЗ рд╣реИрдВ:
function extract(fetched, src, base) { return extractRaw(fetched) .map(href => url.resolve(src, href)) .filter(dst => /^https?\:\/\
рдпрд╣рд╛рдВ
рднреНрд░реВрдг рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдХрд╛рд░реНрдп рд╣реИ,
src рд╕реНрд░реЛрдд рдкреГрд╖реНрда рдХрд╛ URL рд╣реИ,
рдЖрдзрд╛рд░ рдХреНрд░реЙрд▓ рдХрд╛ рдЖрдзрд╛рд░ URL рд╣реИред рдЖрдЙрдЯрдкреБрдЯ рдкрд░, рд╣рдореЗрдВ рдЖрдЧреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдкреВрд░реНрдг рдЖрдВрддрд░рд┐рдХ рд▓рд┐рдВрдХ (URL) рдХреА рдПрдХ рд╕реВрдЪреА рдорд┐рд▓рддреА рд╣реИред рд╕рдВрдкреВрд░реНрдг рдлрд╝рдВрдХреНрд╢рди рдХреЛрдб
рдпрд╣рд╛рдВ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛
рд╣реИ ред
5. URL рд╕рд╛рдорд╛рдиреНрдпреАрдХрд░рдг
рдХрд┐рд╕реА рднреА URL рдХреЛ рд░реА-рдПрдирдХрд╛рдЙрдВрдЯрд░ рдХрд░рдиреЗ рдкрд░, рдЖрдкрдХреЛ рд╕рдВрд╕рд╛рдзрди рдХреЗ рд▓рд┐рдП рджреВрд╕рд░рд╛ рдЕрдиреБрд░реЛрдз рднреЗрдЬрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдбреЗрдЯрд╛ рдкрд╣рд▓реЗ рд╣реА рдкреНрд░рд╛рдкреНрдд рд╣реЛ рдЪреБрдХрд╛ рд╣реИ (рдпрд╛ рдХреЛрдИ рдЕрдиреНрдп рдХрдиреЗрдХреНрд╢рди рдЕрднреА рднреА рдЦреБрд▓рд╛ рд╣реИ рдФрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░ рд░рд╣рд╛ рд╣реИ)ред рд▓реЗрдХрд┐рди рдЗрд╕реЗ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рджреЛ URL рдХреЗ рддрд╛рд░ рдХреА рддреБрд▓рдирд╛ рдХрд░рдирд╛ рд╣рдореЗрд╢рд╛ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред рд╕рд┐рдЪреБрдПрд╢рди рдЕрд▓рдЧ-рдЕрд▓рдЧ URL рдХреЗ рд╕рдорддреБрд▓реНрдп рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд╛рдорд╛рдиреНрдпреАрдХрд░рдг рдЖрд╡рд╢реНрдпрдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╣реИред
рд╕рд╛рдорд╛рдиреНрдпреАрдХрд░рдг рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╕реНрд░реЛрдд URL рдФрд░ рдЙрд╕рдХреЗ рдШрдЯрдХреЛрдВ рдкрд░ рд▓рд╛рдЧреВ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХрд╛ рдПрдХ рдкреВрд░рд╛ рд╕реЗрдЯ рд╣реИред рдпрд╣рд╛рдБ рдЙрдирдореЗрдВ рд╕реЗ рдХреБрдЫ рд╣реА рд╣реИрдВ:
- рдпреЛрдЬрдирд╛ рдФрд░ рдореЗрдЬрдмрд╛рди рд╕рдВрд╡реЗрджрдирд╢реАрд▓ рдирд╣реАрдВ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдЙрдиреНрд╣реЗрдВ рдирд┐рдореНрди рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
- рд╕рднреА рдкреНрд░рддрд┐рд╢рдд (рдЬреИрд╕реЗ "% 3A") рдЕрдкрд░рдХреЗрд╕ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
- рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдкреЛрд░реНрдЯ (HTTP рдХреЗ рд▓рд┐рдП 80) рдХреЛ рд╣рдЯрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
- рдЯреБрдХрдбрд╝рд╛ ( # ) рд╕рд░реНрд╡рд░ рдХреЗ рд▓рд┐рдП рдХрднреА рднреА рджрд┐рдЦрд╛рдИ рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рд╣рдЯрд╛рдпрд╛ рднреА рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдЖрдк рд╣рдореЗрд╢рд╛ рдХреБрдЫ рддреИрдпрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП,
рд╕рд╛рдорд╛рдиреНрдп-рдпреВрдЖрд░рдПрд▓ ) рдпрд╛ рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдФрд░ рд╕рд╛рдорд╛рдиреНрдп рдорд╛рдорд▓реЛрдВ рдХреЛ рдХрд╡рд░ рдХрд░рддреЗ рд╣реБрдП рдЕрдкрдирд╛ рдЦреБрдж рдХрд╛ рд╕рд░рд▓ рдХрд╛рд░реНрдп рд▓рд┐рдЦреЗрдВ:
function normalize(dst) { let dstUrl = new URL(dst);
рдмрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, URL рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдкреНрд░рд╛рд░реВрдк рд╣рд╛рдВ, рдХреНрд╡реЗрд░реА рдкреИрд░рд╛рдореАрдЯрд░ рдХреА рдХреЛрдИ рдЫрдБрдЯрд╛рдИ рдирд╣реАрдВ рд╣реИ,
utm рдЯреИрдЧреНрд╕ рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд░рдирд╛,
_escaped_fragment_ рдФрд░ рдЕрдиреНрдп рдЪреАрдЬреЛрдВ рдХреЛ рдкреНрд░реЛрд╕реЗрд╕
рдХрд░рдирд╛ , рдЬрд┐рд╕рдХреА рд╣рдореЗрдВ (рдмрд┐рд▓реНрдХреБрд▓) рдЬрд╝рд░реВрд░рдд рдирд╣реАрдВ рд╣реИред
рдЕрдЧрд▓рд╛, рд╣рдо рдХреНрд░реЙрд▓ рдврд╛рдВрдЪреЗ рджреНрд╡рд╛рд░рд╛ рдЕрдиреБрд░реЛрдзрд┐рдд рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд URL рдХрд╛ рдПрдХ рд╕реНрдерд╛рдиреАрдп рдХреИрд╢ рдмрдирд╛рдПрдВрдЧреЗред рдЕрдЧрд▓рд╛ рдЕрдиреБрд░реЛрдз рднреЗрдЬрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдкреНрд░рд╛рдкреНрдд URL рдХреЛ рд╕рд╛рдорд╛рдиреНрдп рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдпрджрд┐ рдпрд╣ рдХреИрд╢ рдореЗрдВ рдирд╣реАрдВ рд╣реИ, рддреЛ рдЗрд╕реЗ рдЬреЛрдбрд╝реЗрдВ рдФрд░ рдЙрд╕рдХреЗ рдмрд╛рдж рд╣реА рдПрдХ рдирдпрд╛ рдЕрдиреБрд░реЛрдз рднреЗрдЬреЗрдВред
6. рдореБрдЦреНрдп рдХрд╛рд░реНрдп рдХрд╛ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо
рд╕рдорд╛рдзрд╛рди рдХреЗ рдкреНрд░рдореБрдЦ рдШрдЯрдХ (рдЖрджрд┐рдо) рддреИрдпрд╛рд░ рд╣реИрдВ, рдпрд╣ рд╕рдм рдХреБрдЫ рдПрдХ рд╕рд╛рде рдЗрдХрдЯреНрдард╛ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░рдиреЗ рдХрд╛ рд╕рдордп рд╣реИред рдЖрд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдЗрдП
рдХреНрд░реЙрд▓ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХрд╛ рдирд┐рд░реНрдзрд╛рд░рдг рдХрд░реЗрдВ: рдЗрдирдкреБрдЯ рдкрд░, рдЖрд░рдВрдн URL рдФрд░ рдкреГрд╖реНрда рд╕реАрдорд╛ред рдлрд╝рдВрдХреНрд╢рди рдПрдХ рд╡рд╛рджрд╛ рд▓реМрдЯрд╛рддрд╛ рд╣реИ рдЬрд┐рд╕рдХрд╛ рд╕рдВрдХрд▓реНрдк рдПрдХ рд╕рдВрдЪрд┐рдд рдкрд░рд┐рдгрд╛рдо рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ; рдЗрд╕реЗ
рдЖрдЙрдЯрдкреБрдЯ рдлрд╛рдЗрд▓ рдкрд░ рд▓рд┐рдЦреЗрдВ:
crawl(start, limit).then(result => { fs.writeFile(output, JSON.stringify(result), 'utf8', err => { if (err) throw err; }); });
рдХреНрд░реЙрд▓ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рд╕рдмрд╕реЗ рд╕рд░рд▓ рдкреБрдирд░рд╛рд╡рд░реНрддреА рд╡рд░реНрдХрдлрд╝реНрд▓реЛ рдЪрд░рдгреЛрдВ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
1. рдХреИрд╢ рдХрд╛ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдкрд░рд┐рдгрд╛рдо рдФрд░ рдкрд░рд┐рдгрд╛рдо рд╡рд╕реНрддреБ
2. рдпрджрд┐ рд▓реИрдВрдбрд┐рдВрдЧ рдкреГрд╖реНрда URL ( рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ) рдХреИрд╢ рдореЗрдВ рдирд╣реАрдВ рд╣реИ, рддреЛ
- 2.1ред IF рд╕реАрдорд╛ рд╕рдорд╛рдкреНрдд рд╣реЛ рдЧрдИ рд╣реИ, END (рдкрд░рд┐рдгрд╛рдо рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реЗрдВ)
- 2.2ред рдХреИрд╢ рдореЗрдВ URL рдЬреЛрдбрд╝реЗрдВ
- 2.3ред рдкрд░рд┐рдгрд╛рдо рдореЗрдВ рд╕реНрд░реЛрдд рдФрд░ рд▓реИрдВрдбрд┐рдВрдЧ рдкреГрд╖реНрда рдХреЗ рдмреАрдЪ рд▓рд┐рдВрдХ рд╕рд╣реЗрдЬреЗрдВ
- 2.4ред рдкреНрд░рддрд┐ рдкреГрд╖реНрда рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдЕрдиреБрд░реЛрдз рднреЗрдЬреЗрдВ ( рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ )
- 2.5ред рдпрджрд┐ рдЕрдиреБрд░реЛрдз рд╕рдлрд▓ рд╣реИ, рддреЛ
- - 2.5.1ред рдкрд░рд┐рдгрд╛рдо рд╕реЗ рдирдП рд▓рд┐рдВрдХ рдирд┐рдХрд╛рд▓реЗрдВ ( рдирд┐рдХрд╛рд▓реЗрдВ )
- - 2.5.2ред рдкреНрд░рддреНрдпреЗрдХ рдирдП рд▓рд┐рдВрдХ рдХреЗ рд▓рд┐рдП, рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо 2-3 рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдВ
- 2.6ред ELSE рдкреГрд╖реНрда рдХреЛ рддреНрд░реБрдЯрд┐ рдХреЗ рд░реВрдк рдореЗрдВ рдЪрд┐рд╣реНрдирд┐рдд рдХрд░рддрд╛ рд╣реИ
- 2.7ред рдкрд░рд┐рдгрд╛рдо рдХреЗ рд▓рд┐рдП рдкреГрд╖реНрда рдбреЗрдЯрд╛ рд╕рд╣реЗрдЬреЗрдВ
- 2.8ред рдпрджрд┐ рдпрд╣ рдЕрдВрддрд┐рдо рдкреГрд╖реНрда рдерд╛, рддреЛ рдкрд░рд┐рдгрд╛рдо рд▓рд╛рдПрдВ
3. рдИрдПрд▓рдПрд╕рдИ рдкрд░рд┐рдгрд╛рдо рдореЗрдВ рд╕реНрд░реЛрдд рдФрд░ рд▓реИрдВрдбрд┐рдВрдЧ рдкреГрд╖реНрда рдХреЗ рдмреАрдЪ рд▓рд┐рдВрдХ рдХреЛ рдмрдЪрд╛рдПрдВ
рд╣рд╛рдВ, рдпрд╣ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдмрдбрд╝реЗ рдмрджрд▓рд╛рд╡реЛрдВ рд╕реЗ рдЧреБрдЬрд░реЗрдЧрд╛ред рдЕрдм, рдПрдХ рдкреБрдирд░рд╛рд╡рд░реНрддреА рд╕рдорд╛рдзрд╛рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдЬрд╛рдирдмреВрдЭрдХрд░ рдорд╛рдереЗ рдкрд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддрд╛рдХрд┐ рдмрд╛рдж рдореЗрдВ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдЕрдВрддрд░ рдХреЛ "рдорд╣рд╕реВрд╕" рдХрд░рдирд╛ рдмреЗрд╣рддрд░ рд╣реЛред рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП рд╡рд░реНрдХрдкреАрд╕ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
function crawl(start, limit = 100) {
рдкреГрд╖реНрда рд╕реАрдорд╛ рдХреА рдЙрдкрд▓рдмреНрдзрд┐ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдЕрдиреБрд░реЛрдз рдХрд╛рдЙрдВрдЯрд░ рджреНрд╡рд╛рд░рд╛ рдЬрд╛рдБрдЪ рдХреА рдЬрд╛рддреА рд╣реИред рджреВрд╕рд░рд╛ рдХрд╛рдЙрдВрдЯрд░ - рдПрдХ рд╕рдордп рдореЗрдВ рд╕рдХреНрд░рд┐рдп рдЕрдиреБрд░реЛрдзреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ - рдкрд░рд┐рдгрд╛рдо рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рддрддреНрдкрд░рддрд╛ рдХреА рдкрд░реАрдХреНрд╖рд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рдо рдХрд░реЗрдЧрд╛ (рдЬрдм рдореВрд▓реНрдп рд╢реВрдиреНрдп рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ)ред рдпрджрд┐ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдЕрдЧрд▓рд╛ рдкреГрд╖реНрда рдирд╣реАрдВ рдорд┐рд▓ рд╕рдХрд╛, рддреЛ рдЗрд╕рдХреЗ рд▓рд┐рдП рд╕реНрдерд┐рддрд┐ рдХреЛрдб рдХреЛ рд╢реВрдиреНрдп рдХреЗ рд░реВрдк рдореЗрдВ рд╕реЗрдЯ рдХрд░реЗрдВред
рдЖрдк (рд╡реИрдХрд▓реНрдкрд┐рдХ рд░реВрдк рд╕реЗ)
рдпрд╣рд╛рдВ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛрдб рдХреЗ рд╕рд╛рде
рдЦреБрдж рдХреЛ
рдкрд░рд┐рдЪрд┐рдд рдХрд░ рд╕рдХрддреЗ
рд╣реИрдВ , рд▓реЗрдХрд┐рди рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рдЖрдкрдХреЛ рд▓реМрдЯреЗ рдкрд░рд┐рдгрд╛рдо рдХреЗ рдкреНрд░рд╛рд░реВрдк рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред
7. рд▓реМрдЯрд╛рдпрд╛ рд╣реБрдЖ рдкрд░рд┐рдгрд╛рдо
рд╣рдо рдПрдХ рдЕрдиреВрдареЗ
рдЖрдИрдбреА рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдХреЛ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рд╡реЗрддрди рд╡реГрджреНрдзрд┐ рдХреЗ рд╕рд╛рде рдкреНрд░рджрддреНрдд рдкреГрд╖реНрдареЛрдВ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╕реНрддреБрдд рдХрд░реЗрдВрдЧреЗ:
let id = 0; let cache = {};
рдкрд░рд┐рдгрд╛рдо рдХреЗ рд▓рд┐рдП, рд╣рдо
рдкреГрд╖реНрдареЛрдВ рдХреА рдПрдХ рд╕рд░рдгреА рдмрдирд╛рдПрдВрдЧреЗ, рдЬрд┐рд╕рдореЗрдВ рд╣рдо рдкреГрд╖реНрда рдкрд░ рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдСрдмреНрдЬреЗрдХреНрдЯ рдЬреЛрдбрд╝реЗрдВрдЧреЗ:
id {рд╕рдВрдЦреНрдпрд╛},
url {string} рдФрд░
рдХреЛрдб {рд╕рдВрдЦреНрдпрд╛ | null} (рдпрд╣ рдЕрдм рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ)ред рд╣рдо рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рдкреГрд╖реНрдареЛрдВ рдХреЗ рдмреАрдЪ
рд▓рд┐рдВрдХ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд░рдгреА рднреА рдмрдирд╛рддреЗ рд╣реИрдВ: (рд╕реНрд░реЛрдд рдкреГрд╖реНрда
рдХреА рдЖрдИрдбреА ),
рд╕реЗ (рд▓реИрдВрдбрд┐рдВрдЧ рдкреГрд╖реНрда
рдХреА рдЖрдИрдбреА )ред
рд╕реВрдЪрдирд╛ рдХреЗ рдкреНрд░рдпреЛрдЬрдиреЛрдВ рдХреЗ рд▓рд┐рдП, рдкрд░рд┐рдгрд╛рдо рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо
рдЖрдИрдбреА рдХреЗ рдЖрд░реЛрд╣реА рдХреНрд░рдо рдореЗрдВ рдкреГрд╖реНрдареЛрдВ рдХреА рд╕реВрдЪреА рдХреЛ рдХреНрд░рдордмрджреНрдз рдХрд░рддреЗ рд╣реИрдВ (рдЖрдЦрд┐рд░рдХрд╛рд░, рдЙрддреНрддрд░ рдХрд┐рд╕реА рднреА рдХреНрд░рдо рдореЗрдВ рдЖрдПрдВрдЧреЗ), рд╣рдо рд╕реНрдХреИрди рдХрд┐рдП рдЧрдП
рдЧрд┐рдирддреА рдкреГрд╖реНрдареЛрдВ рдХреА
рд╕рдВрдЦреНрдпрд╛ рдФрд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рд╕реАрдорд╛ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдкрд░ рдПрдХ рдзреНрд╡рдЬ рдХреЗ рд╕рд╛рде рдкрд░рд┐рдгрд╛рдо рдХреЛ рдкреВрд░рдХ рдХрд░рддреЗ рд╣реИрдВ:
resolve({ pages: pages.sort((p1, p2) => p1.id - p2.id), links: links.sort((l1, l2) => l1.from - l2.from || l1.to - l2.to), count, fin: count < limit });
рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ
рддреИрдпрд╛рд░ рдХреНрд░реЙрд▓рд░ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рд╛рд░рд╛рдВрд╢ рд╣реИ:
node crawl-cli.js --start="<URL>" [--output="<filename>"] [--limit=<int>]
рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рдкреНрд░рдореБрдЦ рдмрд┐рдВрджреБрдУрдВ рдХреЗ рд▓реЙрдЧрд┐рдВрдЧ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реБрдП, рд╣рдо рд╕реНрдЯрд╛рд░реНрдЯрдЕрдк рдкрд░ рдЗрд╕ рддрд░рд╣ рдХреА рддрд╕реНрд╡реАрд░ рджреЗрдЦреЗрдВрдЧреЗ:
$ node crawl-cli.js --start="https://google.com" --limit=20 [2019-02-26T19:32:10.087Z] Start crawl "https://google.com" with limit 20 [2019-02-26T19:32:10.089Z] Request (#1) "https://google.com/" [2019-02-26T19:32:10.721Z] Fetched (#1) "https://google.com/" with code 301 [2019-02-26T19:32:10.727Z] Request (#2) "https://www.google.com/" [2019-02-26T19:32:11.583Z] Fetched (#2) "https://www.google.com/" with code 200 [2019-02-26T19:32:11.720Z] Request (#3) "https://play.google.com/?hl=ru&tab=w8" [2019-02-26T19:32:11.721Z] Request (#4) "https://mail.google.com/mail/?tab=wm" [2019-02-26T19:32:11.721Z] Request (#5) "https://drive.google.com/?tab=wo" ... [2019-02-26T19:32:12.929Z] Fetched (#11) "https://www.google.com/advanced_search?hl=ru&authuser=0" with code 200 [2019-02-26T19:32:13.382Z] Fetched (#19) "https://translate.google.com/" with code 200 [2019-02-26T19:32:13.782Z] Fetched (#14) "https://plus.google.com/108954345031389568444" with code 200 [2019-02-26T19:32:14.087Z] Finish crawl "https://google.com" on count 20 [2019-02-26T19:32:14.087Z] Save the result in "result.json"
рдФрд░ рдпрд╣рд╛рдБ JSON рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рдкрд░рд┐рдгрд╛рдо рд╣реИ:
{ "pages": [ { "id": 1, "url": "https://google.com/", "code": 301 }, { "id": 2, "url": "https://www.google.com/", "code": 200 }, { "id": 3, "url": "https://play.google.com/?hl=ru&tab=w8", "code": 302 }, { "id": 4, "url": "https://mail.google.com/mail/?tab=wm", "code": 302 }, { "id": 5, "url": "https://drive.google.com/?tab=wo", "code": 302 }, // ... { "id": 19, "url": "https://translate.google.com/", "code": 200 }, { "id": 20, "url": "https://calendar.google.com/calendar?tab=wc", "code": 302 } ], "links": [ { "from": 1, "to": 2 }, { "from": 2, "to": 3 }, { "from": 2, "to": 4 }, { "from": 2, "to": 5 }, // ... { "from": 12, "to": 19 }, { "from": 19, "to": 8 } ], "count": 20, "fin": false }
рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рд╣реА рдХреНрдпрд╛ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ? рдХрдо рд╕реЗ рдХрдо, рдкреГрд╖реНрдареЛрдВ рдХреА рд╕реВрдЪреА рдЖрдк рд╕рд╛рдЗрдЯ рдХреЗ рд╕рднреА рдЯреВрдЯреЗ рд╣реБрдП рдкреГрд╖реНрда рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред рдФрд░ рдЖрдВрддрд░рд┐рдХ рд▓рд┐рдВрдХрд┐рдВрдЧ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рд╣реЛрдиреЗ рдкрд░, рдЖрдк рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдХреА рд▓рдВрдмреА рд╢реНрд░реГрдВрдЦрд▓рд╛рдУрдВ (рдФрд░ рдмрдВрдж рдЫреЛрд░реЛрдВ) рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдпрд╛ рд╕рдВрджрд░реНрдн рджреНрд░рд╡реНрдпрдорд╛рди рджреНрд╡рд╛рд░рд╛ рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдкреГрд╖реНрда рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред
рдШреЛрд╖рдгрд╛ 2.0
рд╣рдордиреЗ рд╕рдмрд╕реЗ рд╕рд░рд▓ рдХрдВрд╕реЛрд▓ рдХреНрд░реЙрд▓рд░ рдХрд╛ рдПрдХ рд╕рдВрд╕реНрдХрд░рдг рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рд╣реИ, рдЬреЛ рдПрдХ рд╕рд╛рдЗрдЯ рдХреЗ рдкреГрд╖реНрдареЛрдВ рдХреЛ рджрд░рдХрд┐рдирд╛рд░ рдХрд░рддрд╛ рд╣реИред рд╕реНрд░реЛрдд рдХреЛрдб
рдпрд╣рд╛рдБ рд╣реИ рдХреБрдЫ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрджрд╛рд╣рд░рдг рдФрд░
рдЗрдХрд╛рдИ рдкрд░реАрдХреНрд╖рдг рднреА рд╣реИред
рдЕрдм рдпрд╣ рдЕрдиреБрд░реЛрдзреЛрдВ рдХрд╛ рдПрдХ рдирд┐рд╕реНрд╕рдВрджреЗрд╣ рдкреНрд░реЗрд╖рдХ рд╣реИ рдФрд░ рдЕрдЧрд▓рд╛ рдЙрдЪрд┐рдд рдХрджрдо рдЙрд╕реЗ рдЕрдЪреНрдЫреЗ рд╢рд┐рд╖реНрдЯрд╛рдЪрд╛рд░ рд╕рд┐рдЦрд╛рдирд╛ рд╣реЛрдЧрд╛ред рдпрд╣
рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛-рдПрдЬреЗрдВрдЯ рд╣реЗрдбрд░,
robots.txt рдирд┐рдпрдореЛрдВ,
рдХреНрд░реЙрд▓-рджреЗрд░реА рдирд┐рд░реНрджреЗрд╢, рдФрд░ рдмрд╣реБрдд рдХреБрдЫ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣реЛрдЧрд╛ред рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ, рдпрд╣ рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рд╕рдВрджреЗрд╢реЛрдВ рдХреЛ рдХрддрд╛рд░рдмрджреНрдз рдХрд░рддрд╛ рд╣реИ рдФрд░ рдлрд┐рд░ рдПрдХ рдмрдбрд╝реЗ рднрд╛рд░ рдХреА рд╕рд░реНрд╡рд┐рд╕рд┐рдВрдЧ рдХрд░рддрд╛ рд╣реИред
рдЕрдЧрд░, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдпрд╣ рд╕рд╛рдордЧреНрд░реА рджрд┐рд▓рдЪрд╕реНрдк рд╣реЛрдЧреА!