Node js Scrapper - PullRequest
       33

Node js Scrapper

0 голосов
/ 15 февраля 2019

Я написал скребок для машинописного текста, работающий на узле : 10.12.0 ,

Проблема: Код переходит в спящий режим через несколько часов, случайно.И мне пришлось его перезапустить.Мое лучшее предположение, что он застрял на URL-запросе

Инструменты / пакеты Использование:

  • Кукольник
  • Cheerio
  • Машинопись

Код:

import * as cheerio from "cheerio";
import * as request from "request";
import * as fs from "fs";
import * as shell from "shelljs";
import pup = require("puppeteer");
class App {
    // @ts-ignore
    public browser: pup.Browser;
    public appendToFile(file: string, content: string): Promise < string > {
        return new Promise < string > ((resolve, reject) => {
            try {
                fs.appendFileSync(file, content);
                resolve("DONE");
            } catch (e) {
                reject(e);
            }
        });
    }
    public loadPage(url: string): Promise < any > {
        return new Promise < any > ((resolve, reject) => {
            request.get(url, async (err, res, html) => {
                if (!err && res.statusCode === 200) {
                    resolve(html);
                } else {
                    if (err) {
                        reject(err);
                    } else {
                        reject(res);
                    }
                }
            });
        });
    }
    public step1(url: string): Promise < string > {
        return new Promise < string > (async (resolve, reject) => {
            let page: pup.Page | undefined;
            try {
                let next = false;
                let urlLink = url;
                let first = true;
                let header = "unknown";
                let f = url.split("/");
                let folder = f[f.length - 3];
                folder = folder || header;
                let path = "data/" + folder;
                shell.mkdir("-p", path);
                page = await this.browser.newPage();

                await page.goto(url, {
                    timeout: 0
                });
                let count = 1;
                do {
                    next = false;
                    let res = await page.evaluate(() => {
                        let e = document.querySelectorAll(".ch-product-view-list-container.list-view li ul > li > h6 > a");
                        let p: string[] = [];
                        e.forEach((v) => {
                            p.push(("https://www.link.com") + (v.getAttribute("href") as string));
                        });
                        return p;
                    });

                    // for(const l of res) {
                    //     try {
                    //         await this.step2(l, "" , "")
                    //     } catch(er) {
                    //         this.appendToFile("./error.txt", l + "::" + url + "\n").catch(e=>e)
                    //     }
                    // }

                    let p = [];
                    let c = 1;
                    for (const d of res) {
                        p.push(await this.step2(d, folder, c.toString()).catch((_e) => {
                            console.log(_e);
                            fs.appendFileSync("./error-2.txt", urlLink + " ### " + d + "\n");
                        }));
                        c++;
                    }
                    await Promise.all(p);

                    await this.appendToFile("./processed.txt", urlLink + ":" + count.toString() + "\n").catch(e => e);
                    count++;
                    console.log(urlLink + ":" + count);
                    let e = await page.evaluate(() => {
                        let ele = document.querySelector("#pagination-next") as Element;
                        let r = ele.getAttribute("style");
                        return r || "";
                    });
                    if (e === "") {
                        next = true;

                        await page.click("#pagination-next");
                        // console.log('waitng')
                        await page.waitFor(1000);
                        // console.log('done wait')
                        // await page.waitForNavigation({waitUntil: 'load'}).catch(e=> console.log(e));
                        //     await Promise.all([
                        //         page.click("#pagination-next"),
                        //         page.waitForNavigation({ waitUntil: 'networkidle0'}),                //   ]);
                    }
                } while (next);
                // await page.close();
                resolve("page all scrapped");
            } catch (errrr) {
                reject(errrr);
            } finally {
                if (page !== undefined) {
                    await page.close().catch(e => e);
                }
            }
        });
    }
    public step2(url: string, folder: string, file: string): Promise < string > {
        return new Promise < string > (async (resolve, reject) => {
            try {
                let html = await this.loadPage(url).catch(e => reject(e));
                let $ = cheerio.load(html);
                let ress: any = {};
                let t = $(".qal_title_heading").text();
                if (t) {
                    ress.header = t.replace(/"/g, "'").replace(/\n|\r|\t/g, "");
                }
                let d = $("div.ch_formatted_text.qal_thread-content_text.asker").html();
                if (d) {
                    ress.body = d.replace(/"/g, "'").replace(/\n|\r|\t/g, "");
                }
                // let sprit = "-------------------------------";
                let filename = "data" + file + ".json"; // ((t.replace(/[^\w\s]/gi, "")).substring(0,250)+".txt")
                let data = JSON.stringify(ress) // t +sprit + d + "\n---end---\n";                await this.appendToFile("./data/"+ folder + "/" +filename, data+",\n")
                    .then((r) => {
                        resolve(r);
                    });
            } catch (err) {
                reject(err);
            }
        });
    }
}
async function main() {
    process.on("SIGTERM", () => {
        console.log("SigTerm received");
        process.exit(1);
    });
    process.on("SIGINT", () => {
        console.log("SigInt received");
        process.exit(1);
    });
    let path = "data/unknown";
    shell.mkdir("-p", path);
    let c = new App();
    let list: string[] = [];
    console.log(process.argv[2]);
    require("fs").readFileSync(process.argv[2], "utf-8").split(/\r?\n/).forEach((line: string) => {
        list.push(line);
    });
    console.log("total links->" + list.length);

    c.browser = await pup.launch({
        headless: true
    });
    for (const l of list) {
        await c.step1(l).then(e => {
            fs.appendFileSync("./processed.txt", l);
        }).catch(e => {
            fs.appendFileSync("./error.txt", l);
        });
    }
}
main();

Дайте мне знать, если вам нужно что-то еще от меня.Также это весь код.

1 Ответ

0 голосов
/ 18 февраля 2019

Итак, я понял две проблемы.

  1. Хром (при кукловоде) потребляет высокий процессор, что дает такую ​​тенденцию:

    при запуске - при умеренном использовании.и это постепенно увеличивается.Моя тенденция заключалась в том, что он начинался с 4% использования, а через день достиг 100%.Я отправил вопрос об их git

  2. Я не указал время ожидания в запросе

    было:

    request.get(url, async (err, res, html) => { 
    

    должно быть:

    request.get(url,{timeout: 1500} async (err, res, html) => {
    

Пока мой код работает нормально уже более суток.Единственная проблема - высокая загрузка процессора.Но на данный момент это не мое дело.

...