CoderCastrov logo
CoderCastrov
JavaScript

Как эффективно извлечь информацию из data.gov.in

Как эффективно извлечь информацию из data.gov.in
просмотров
4 мин чтение
#JavaScript

4 шага для извлечения любого объема данных с использованием node.js

Я решил написать этот блог-пост, потому что считаю, что это может помочь многим людям получить легкий доступ к данным, предоставляемым правительством. Кроме того, процесс извлечения информации с сайта является трудоемким, поскольку данные разделены на тысячи точек данных, которые необходимо загружать индивидуально.

Извлечение данных из data.gov.in не так просто, и это довольно длительный процесс, который включает несколько шагов.

В этой статье мы рассмотрим четыре основных шага по загрузке данных с data.gov.in:

Давайте перейдем к первому шагу!

1. Найдите шаблон, относящийся к данным, которые вы хотите скачать

На следующем gif-изображении я покажу, как найти шаблон, относящийся к данным о производительности ключевых показателей HMIS по районам:

Pattern recognition

2. Определите, какую информацию и данные вам нужно

В этом руководстве мы собираемся получить информацию, такую как название района, год и месяц, а также JSON-файл для каждой точки данных.

После изучения заголовка и элементов данных с помощью инструмента "Инспектировать элемент", мы определяем HTML-теги, которые веб-сайт использует для этой конкретной информации, которую мы будем использовать позже.

3. Использование правильного набора библиотек Node.js

Мы собираемся использовать мощные библиотеки Node.js, которые также используются для тестирования и контроля качества во многих компаниях. Для наших целей они идеально подходят.

Начните с создания проекта Node и установки puppeteer и его зависимостей с помощью npm.

Мы собираемся писать асинхронный код на ES6-javascript.

const puppeteer = require('puppeteer');
const fs = require('fs');
var download = require('download-file');

После импорта зависимостей мы пишем функцию, которая помогает сохранить URL-адреса для файлов JSON. Не забудьте использовать правильные соглашения по именованию файлов.

const save = async (value,state,district) => {
    var jsonContent = JSON.stringify(value);    var dir = ".\\WholeUrls\\"+state;    if (!fs.existsSync(dir)){
        fs.mkdirSync(dir);
    }    saveLoc=".\\WholeUrls\\"+state+"\\"+district+".json"
    fs.writeFile(saveLoc, jsonContent, 'utf8', function (err) {
    if (err) {
        console.log("Произошла ошибка при записи объекта JSON в файл.");
        return console.log(err);
    }
    console.log("Файл JSON был сохранен.");});
}

Затем мы пишем функцию для парсинга страницы:

const scrapePage =async (page) => page.evaluate(() => {let url = []; //Пустой массив для URL-адресов
    let title = [];
    let elements = document.querySelectorAll('.csv'); 
    for (var element of elements){
        url.push(element.href);
    }elements = document.querySelectorAll('.title-content');
    for (var element of elements){ 
        title.push(element.innerText);
    }let data = {title,url};return data;
})

Вышеуказанный код использует библиотеку puppeteer для навигации по 1 странице. Как мы видели на GIF-изображении, каждая страница содержит 6 точек данных. Таким образом, приведенный выше код запускает и извлекает информацию и данные о 6 точках данных.

Но согласно нашим экспериментам, если вам нужно извлечь данные для примерно 22 000 существующих точек данных, нам нужно добавить возможность навигации в наш код. Так, чтобы он самостоятельно перемещался и выполнялся, пока успешно не загрузит все данные.

let scrape = async (district="BAKSA",state="ASSAM") => {
    console.log("Начался парсинг для ", district)
    let iterator=0;
    d=district.toLowerCase()
    d1=""for(const i in d){
        if(i!=' ') d1+=d[i]; else break;
    }const browser = await puppeteer.launch({headless: false});
    const page = await browser.newPage();
    //для всех URL-адресов
    urls=[]
    uRl='[https://data.gov.in/search/site?filter%5Bnew_title'](https://data.gov.in/search/site?filter%5Bnew_title%5D=farmers+queries+kisan+call+centre+%27+d1+%27+district+month%27)
    await page.goto(uRl);
    i1=1;
    while (1){
        for (let i = 0; i < 10; ++i) {
            let Result;
            
            Result = `#ogpl-cust-result-html-wrap > div:nth-child(${i + 1}) > h3 > a`;
            
            try{
                await page.waitFor(Result, {visible: true});
            }    
            catch(err){
                console.log("Пришли сюда")
                i1=0;
                break;
            }
            err1=false;
        
            page.click(Result);
            try{
                await page.waitForNavigation({waituntil:'networkidle2'});
            }
            catch(err){
                console.log("поймана ошибка:",err);
                err1=true;
            }
            if(!err1){
            //const url = page.evaluate(()=> {uRL= document.querySelector('.csv');return uRL.href;})
            try{
                url= await scrapePage(page);
                urls.push(url);
            }
            catch(err){
                console.log("ошибка страницы:",err);
            }
            my=(url["title"][0]).split(" ");
            year=my[my.length-1];
            month=my[my.length-2];options = {
                directory: "./WholeData/"+state+"/"+district+"/",
                filename: year+" "+month+".csv",
                timeout: 2000000
            };
            
            })
            }
            await page.waitFor(1000);
            await page.goBack();
            await page.waitFor(2000);
        }
        if(i1==0)
                break;let Result = `#ogpl-cust-result-pager-wrap > div > ul > li:nth-child(2) > a`;
        try{
            await page.waitFor(Result, {visible: true});
        }
        catch(err){
            Result = `#ogpl-cust-result-pager-wrap > div > ul > li > a`;
        }
        page.click(Result);
        try{
            await page.waitForNavigation({waituntil:'networkidle2'});
        }
        catch(err){
            console.log("Ошибка:",err);
        }
    }browser.close();if(JSON.stringify(urls)!="[]")
        save(urls,state,district)return new Promise((resolve)=> resolve('resolved'));};module.exports =    {scrape};

4. Используйте download.js для сохранения загруженных данных в организованном формате

my=(url["title"][0]).split(" ");
            year=my[my.length-1];
            month=my[my.length-2];options = {
                directory: "./WholeData/"+state+"/"+district+"/",
                filename: year+" "+month+".csv",
                timeout: 2000000
            };if(url)
   download(url["url"][0], options, function(err){
if (err) {console.log(url["url"][0],err);return err;}
else {console.log(url["url"][0], "location=",state,district,month,year,"meow");return true};

Функция сохраняет данные в папке с названием "WholeData", с определенным именем файла и соответствующими подпапками.

5. Заключение

В этом руководстве вы узнали, как извлекать любую информацию, которую вы хотите, с сайтов, таких как data.gov.in, которые не могут быть спарсены обычными способами, даже с сайтов, требующих заполнения форм и навигации.