请求和网络抓取时遇到问题

时间:2019-06-05 13:14:03

标签: javascript node.js web-scraping request cheerio

我正在尝试编写向网站发出请求的代码,以进行网络抓取

这是步骤:

此处是代码STARTS的第一部分

  1. 程序向 mainURL
  2. 发送请求
  3. 程序从 mainURL 的html中选择一些对象,并将它们存储在对象属性中的对象数组(广告)中,该对象是链接,我们将对其进行链接调用 numberURL ,代码将使用css选择器自动选择,对象数量大约为80-90;
  4. 程序会向每个 numberURL (80-90个请求)发出请求, 并且为每个对象的确为同一对象设置了另一个属性,并选择了另一个链接,我们将其称为 accountURL
  5. 程序创建一个CSV文件,在其中将每个对象写入不同的行

此处为代码ENDS的第一部分

所以实际上第一部分效果很好,没有任何问题,但是第二部分确实可以

此处是代码STARTS的第二部分

  1. 程序从上一个对象向每个 accountURL 发出请求
  2. 程序从 accountURL 的html中选择一些对象,并使用CSS选择器将它们存储在另一个对象(帐户)的另一个数组中。
  3. 程序应console.log()所有 account 对象

此处是代码ENDS的第二部分

但是第二部分确实存在一些错误,因为在console.logging对象时,我们看到对象属性未更改其默认值。

因此,出于调试目的,我采用了一个advert对象,并通过代码手动将其值

post[0].link = 'https://999.md/ru/profile/denisserj'

最后,当为该对象运行代码时,它实际上可以正常工作,因此它显示了更改后的属性,但对于其余属性却不起作用。

我试图设置一些超时,以为代码试图在第二个请求完成之前读取链接,但是没有效果

我还尝试了console.log链接,以查看它是否存在于数组中,因此它实际上存在于数组中,但也没有效果。

最后是代码:

// CLASSES
class advert {
    constructor() {
        this.id = 0;
        this.tile = new String();
        this.link = new String();
        this.phone = new String();
        this.account = new String();
        this.accountLink = new String();
        this.text = new String();
        this.operator = new String();
    }
    show() {
        console.log(this.id, this.title, this.link, this.phone, this.account, this.accountLink, this.text, this.operator);
    }

}
class account {
    constructor() {
        this.name = 0;
        this.createdAt = 0;
        this.phone = [];
        this.ads = [];
        this.adsNumber = 0;
    }
    show() {
        console.log(this.name, this.createdAt, this.phone, this.ads, this.adsNumber);
    }
}

// HEADERS
const mainRequest = require('request');
const auxRequest = require('request');
const cheerio1 = require('cheerio');
const cheerio2 = require('cheerio');
const fs = require('fs');
const fs2 = require('fs');
const adFile = fs.createWriteStream('anunturi.csv');
const accFile = fs2.createWriteStream('conturi.csv');

// SETTINGS
const host = 'https://999.md'
const category = 'https://999.md/ru/list/transport/cars'
const timeLimit = 60; //seconds

// VARIABLES
let post = [];
let postNumber = 0;
let acc = [];

// FUNCTIONS
function deleteFromArray(j) {
    post.splice(j, 1);
}

function number(i) {
    let category = post[i].link;
    auxRequest(category, (error, response, html) => {
        if (!error && response.statusCode == 200) {
            const $ = cheerio1.load(html);
            let phone;
            const siteTitle = $('strong').each((id, el) => {
                phone = $(el).text();
            });
            const txt = $('.adPage__content__description').html();
            const person = $('.adPage__header__stats').find('.adPage__header__stats__owner').text();
            const linkToPerson = host + $('.adPage__header__stats').find('.adPage__header__stats__owner').find('a').attr('href');
            post[i].phone = phone;
            post[i].account = person;
            post[i].accountLink = linkToPerson;
            post[i].text = txt;
            if (i == postNumber) {
                console.log('1. Number Putting done')
                writeToFileAd(accountPutter, writeToFileAccount);
            }
        }

    });
}

function writeToFileAd() {
    adFile.write('ID, Titlu, Link, Text, Cont, LinkCont, Operator\n')
    for (let i = 0; i <= postNumber; i++) {
        adFile.write(`${post[i].id}, ${post[i].title}, ${post[i].link}, ${post[i].phone}, ${post[i].account}, ${post[i].accountLink}, ${post[i].operator}\n`);
    }
    console.log('2. Write To File Ad done')
    accountPutter();
}

function accountAnalyzis(i) {
    let category = post[i].link;
    const mainRequest = require('request');
    category = category.replace('/ru/', '/ro/');
    mainRequest(category, (error, response, html) => {

        if (!error && response.statusCode == 200) {
            const $ = cheerio2.load(html);
            const name = $('.user-profile__sidebar-info__main-wrapper').find('.login-wrapper').text();
            let createdAt = $('.date-registration').text();
            createdAt = createdAt.replace('Pe site din ', '');
            const phones = $('.user-profile__info__data').find('dd').each((id, el) => {
                let phone = $(el).text();
                acc[i].phone.push(phone);
            });
            const ads = $('.profile-ads-list-photo-item-title').find('a').each((id, el) => {
                let ad = host + $(el).attr('href');
                acc[i].ads.push(ad);
                acc[i].adsNumber++;
            });
            acc[i].name = name;
            acc[i].createdAt = createdAt;
            console.log(name)
            if (i == postNumber) {
                console.log('3. Account Putting done')
                writeToFileAccount();
            }
        }
    });
}

function writeToFileAccount() {
    for (let i = 0; i <= postNumber; i++) {
        accFile.write(`${acc[i].name}, ${acc[i].createdAt}, ${acc[i].phone}, ${acc[i].ads}, ${acc[i].adsNumber}\n`);
    }
    console.log('4. Write to file Account done');
}

function numberPutter() {
    for (let i = 0; i <= postNumber; i++) {
        number(i);
    }
}

function accountPutter() {
    for (let i = 0; i <= postNumber; i++) {
        accountAnalyzis(i);
    }
}

// MAIN
mainRequest(category, (error, response, html) => {
    let links = [];
    for (let i = 0; i < 1000; i++) {
        post[i] = new advert();
    }
    for (let i = 0; i < 1000; i++) {
        acc[i] = new account();
    }
    if (!error && response.statusCode == 200) {
        const $ = cheerio2.load(html);
        const siteTitle = $('.ads-list-photo-item-title').each((id, el) => {
            const ref = host + $(el).children().attr('href');
            const title = $(el).text();
            post[id].id = id + 1;
            post[id].title = title;
            post[id].link = ref;
            links[id] = ref;
            postNumber = id;
        });
        post[0].link = 'https://999.md/ru/profile/denisserj'
        numberPutter()
    }

});

1 个答案:

答案 0 :(得分:0)

您在一行中遇到错误

const siteTitle = $('.ads-list-photo-item-title').each((id, el) => {

您真正想要的是.find('a').each...