Web scraping con java

di il
6 risposte

Web scraping con java

Buongiorno programmatori
premetto che non sono un programmatore java e sono qui per chiedervi una soluzione. Ho girato su google per cercare risposte a questo:
package Software;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Scanner;
import java.util.regex.Pattern;

public class DownloadBilanci {

    private static final Pattern TAG_REGEX = Pattern.compile("<table>(.+?)*</table>");

    public static void main(String[] args) throws MalformedURLException, FileNotFoundException, IOException {

        final List<String> tagValues = new ArrayList<String>();
        String[] city = new String[9000];
        String[] quadri = new String[20];
        String[] file = new String[20];
        int contCity = 0;
        File anagrafiche = new File("C:\\Users\\chita\\Desktop\\IRESofware\\Anagrafiche.txt"); //apro file
        Scanner scan = new Scanner(anagrafiche);

        while (scan.hasNextLine()) { //ciclo il contenuto del file fino alla fine
            String line = scan.nextLine(); //scarico il contenuto
            String[] parts = line.split(";");
            city[contCity] = parts[0];
            contCity++;
        }

        scan.close();

        file[0] = "Quadro1.csv";
        file[1] = "Quadro2.csv";
        file[2] = "Quadro3.csv";
        file[3] = "Quadro4.csv";
        file[4] = "Quadro5.csv";
        file[5] = "Quadro6.csv";
        file[6] = "Quadro8.csv";
        file[7] = "Quadro9.csv";
        file[8] = "Quadro10.csv";
        file[9] = "Quadro11.csv";
        file[10] = "Quadro12.csv";
        file[11] = "Quadro13.csv";
        file[12] = "Quadro14.csv";
        file[13] = "Quadro15.csv";
        file[14] = "Quadro50.csv";

        quadri[0] = "01";
        quadri[1] = "02";
        quadri[2] = "03";
        quadri[3] = "04";
        quadri[4] = "05";
        quadri[5] = "06";
        quadri[6] = "08";
        quadri[7] = "09";
        quadri[8] = "10";
        quadri[9] = "11";
        quadri[10] = "12";
        quadri[11] = "13";
        quadri[12] = "14";
        quadri[13] = "15";
        quadri[14] = "50";
        

        for (int g = 7; g < 15; g++) {
            System.out.println("Inizio analisi del quadro " + quadri[g]);
            
            for (int c = 0; c < city.length; c++) {
                try {
                    //URL url = new URL("http://finanzalocale.interno.it/apps/floc.php/certificati/index/codice_ente/" + city[c] + "/cod/4/anno/2012/md/0/cod_modello/CCOU/tipo_modello/U/cod_quadro/" + quadri[g] + "");
                    //URL url = new URL("http://finanzalocale.interno.it/apps/floc.php/certificati/index/codice_ente/" + city[c] + "/cod/4/anno/2016/md/0/cod_modello/CCOX/tipo_modello/X/cod_quadro/" + quadri[g] + "");
                    //URL url = new URL("http://finanzalocale.interno.gov.it/apps/floc.php/certificati/index/codice_ente/" + city[c] + "/cod/4/anno/2016/md/0/cod_modello/CCMX/tipo_modello/X/cod_quadro/" + quadri[g] + "");
                    URL url = new URL("http://finanzalocale.interno.gov.it/apps/floc.php/certificati/index/codice_ente/" + city[c] + "/anno/2017/cod/3/md/0/cod_modello/PCOX/tipo_modello/X/cod_quadro/" + quadri[g] + "");                                     
                    URLConnection myURLConnection = url.openConnection();
                    
                    myURLConnection.connect();
                    BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
                    FileWriter outFile = new FileWriter("C:\\Users\\chita\\Desktop\\IRESofware\\" + file[g] + "", true); //apro file
                    //PrintStream write = new PrintStream(outFile);
                    String extractResult = "";
                    String inputLine;
                    while ((inputLine = in.readLine()) != null) {
                        extractResult = extractResult + "\n" + inputLine;
                        //write.println(inputLine);
                    }

                    extractResult = extractResult.replaceAll("</td>", "</td>\n");
                    extractResult = extractResult.replaceAll("</tr>", "</tr>\n");
                    extractResult = extractResult.replaceAll("<tr>", "<tr>\n");
                    extractResult = extractResult.replaceAll("</th>", "</th>\n");

                    String[] result = extractResult.split("[<table]{6}");

                    /*for(String k:result){
                     write.println("----------------------------------------------------------------------------------------------------------");
                     write.println(k);
                     }*/
                    String nomecittà = "";
                    String codicetitolo = result[1];
                    int posIntestazionetit = codicetitolo.indexOf("<span class=\"titoliblu\">");
                    posIntestazionetit += 148;

                    for (int i = posIntestazionetit; i < codicetitolo.length(); i++) {
                        if (codicetitolo.charAt(i) == '<') {
                            break;
                        }
                        nomecittà = nomecittà + " " + codicetitolo.charAt(i);
                        //System.out.print(part1.toString());
                    }

                    int k = 2;
                    String daticsv = "";
                    while (k < result.length - 1) {
                        String intestazione = "";
                        String part1 = result[k];
                        int posIntestazione = part1.indexOf("<caption>");
                        posIntestazione += 9;

                        for (int i = posIntestazione; i < part1.length(); i++) {
                            if (part1.charAt(i) == '<') {
                                break;
                            }
                            intestazione = intestazione + " " + part1.charAt(i);
                            //System.out.print(part1.toString());
                        }

                        //System.out.println(intestazione.trim());
                        String dati = result[k];
                        Scanner sc = new Scanner(dati);
                        String park = "";
                        int pos = 0;
                        int post1 = 0;
                        int post2 = 0;
                        String valori = "";
                        String resultDati = "";
                        while (sc.hasNextLine()) {
                            park = sc.nextLine();
                            part1 = park;
                            post1 = part1.indexOf("<td class=\"ad\">");
                            post2 = part1.indexOf("<td class=\"tftitvert\">");

                            if (post2 > -1) {
                                pos = post2 + 22;
                            } else if (post1 > -1) {
                                pos = post1 + 15;
                            } else {
                                pos = 0;
                            }
                            //pos += 9;

                            for (int i = pos; i < part1.length(); i++) {
                                if (part1.charAt(i) == '<') {
                                    break;
                                }
                                valori = valori + part1.charAt(i);
                                //System.out.print(part1.toString());
                            }
                            if (valori.matches("[0-9.,-]+")) {
                                resultDati += ";" + valori;
                            }
                            //resultDati += "\n" + valori;
                            valori = "";

                        }

                        //resultDati = resultDati.replaceAll("\n", "");
                        //System.out.println(resultDati.trim());
                        //resultDati = resultDati.replaceAll(";;", ";");
                        daticsv = daticsv + resultDati;
                        k++;
                    }
                    //daticsv = daticsv.replaceAll("\n", ";");
                    daticsv = "\n" + nomecittà + "" + daticsv;
                    //System.out.println(daticsv.trim());
                    outFile.write(daticsv);
                    outFile.close();
                    in.close();

                } catch (MalformedURLException e) {
                    // new URL() failed
                    // ...
                } catch (IOException e) {
                    // openConnection() failed
                    // ...
                }
            }
            System.out.println("Dati scaricati in " + file[g]);
        }
    }

    public static boolean isNumeric(String str) {
        try {
            double d = Double.parseDouble(str);
        } catch (NumberFormatException nfe) {
            return false;
        }
        return true;
    }
}
è un programma (ma ovvio!) di web scraping che serve a scaricare dal sito che vedete nella relativa riga delle tabelle (circa 15) e che si autocompila con il nome delle città mediante il file anagrafiche.txt (spero sia chiara la spiegazione) infine scrive le tabelle in dei file csv.
Il problema sta nella stringa!
String codicetitolo = result[1];
Premetto che l'informatico precedente disse di usare netbeans per far andare il programma e l'errore che mi genera sulla stringa codice titolo è questo
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
	at Software.DownloadBilanci.main(DownloadBilanci.java:118)
.
Ribadisco sul fatto che sono un neofita in materia, ma cambiando il valore da 1 a 0 il programma gira ma scarica file csv vuoti, anche se questi aumentano di peso!
Il quesito è semplice, come lo risolvo il problema?

nb. il programma è molto vecchio ed è passato da informatico ad informatico subendo vari aggiornamenti

6 Risposte

  • Re: Web scraping con java

    Ci sono un paio di considerazioni spicciole:
    1) Netbeans non centra niente: e' solo un editor super evoluto che aiuta la scrittura del programme, NON E' IL PROGRAMMA. C'e' la stessa differenza tra la pentola usata per cucinare la pasta, e la pasta che stai cucinando!
    2) il problema nella stringa in questione e' banale: result e' un vettore, ma ha una lunghezza INFERIORE a 2. Cioe' e' un vettore di lunghezza 0 o uno. In particolare, visto che usando il valotre 0 FUNZIONA< il vettore e' composto da un'UNICO elemento.
    3) perche non funziona'? Questo NON DIPENDE dal programma Java, ma dalle modifiche che sono state fatte sul sito che si sta analizzando.

    La soluzione non e' banale: serve analizzare la pagina HTML originale, e modificare il codice Java del programma di conseguenza.

    Problema: non e' proprio un lavoro per neofiti. Serve qualcuno con esperienza in Java e in applicazioni Web, ed in particolare che sappia anlizzare un documento HTML.
  • Re: Web scraping con java

    marcolo ha scritto:


    Il problema sta nella stringa!
    String codicetitolo = result[1];
    La riga che hai citato è appena dopo di questa:

    String[] result = extractResult.split("[<table]{6}");

    Ma questa riga mi pare un po' "dubbia". Perché [<table] NON vuol dire la stringa "<table" (ripetuta 6 volte) ma è una "classe di caratteri", ovvero corrisponde a: "<" oppure "t" oppure "a" oppure ....ecc...
    Quindi? Cosa si voleva ottenere??

    Dovrei analizzare meglio il contenuto di quelle pagine.

    marcolo ha scritto:


    nb. il programma è molto vecchio ed è passato da informatico ad informatico subendo vari aggiornamenti
    Si vede ..... e purtroppo si vedono le nozioni "basse" su Java.
  • Re: Web scraping con java

    Grazie per le risposte tempestive. Non voglio entrare nel merito di chi abbia scritto questo programma, ho dovuto risolvere cose peggiori!
    Il sito in questione è questo http://finanzalocale.interno.gov.it/apps/floc.php/in/cod/4 , ,basta inserire il nome della città, il codice ente si autocompila, una volta entrati il programma scarica la tabella all'interno della pagina "quadro1","quadro2" ecc.... .
    Pensavo che la soluzione potesse essere più intuitiva e rapida, ma grazie comunque. Cercherò alternative con altri programmi!
  • Re: Web scraping con java

    Oppure dai incarico ad andbin di scrivere il programma in maniera adeguata e moderna, ovviamente dietro compenso.
  • Re: Web scraping con java

    oregon ha scritto:


    Oppure dai incarico ad andbin di scrivere il programma in maniera adeguata e moderna, ovviamente dietro compenso.
    Per quanto mi piacerebbe non credo sia il caso, ma lo ringrazio comunque per la sua risposta. Sono abbastanza certo che a questo punto risolverò il problema in qualche maniera!
  • Re: Web scraping con java

    Te lo suggerivo prima di affidarti ad un altro qualsiasi "informatico" che magari non risolverà ...
Devi accedere o registrarti per scrivere nel forum
6 risposte