JSoup HTML-анализ и запись результатов в CSV по порядку - PullRequest
0 голосов
/ 07 октября 2019

Я пытаюсь найти лучший подход к сохранению данных, которые я проанализировал из документа HTML, когда Jsoup в CSV. У меня проблема с использованием [CSVWriter] [1] - https://mvnrepository.com/artifact/com.opencsv/opencsv/4.6 и записью данных с ним. Пожалуйста, смотрите мой фрагмент кода ниже. Структура данных выглядит следующим образом: инфобокс является основной записной записью с каждым последующим полем внутри нее. CSVWriter выглядит так, как будто это строковый массив, но у него возникают проблемы при переходе от элементов для записи к средству записи CSVData с помощью строкового массива.

Селектор Jsoup возвращает массив элементов из выбора. Например, когда я делаю выбор имени, он возвращает все 9 имен, если на странице 9 записей. Мне нужно собрать эти данные вместе, чтобы каждая строка печаталась в CSV.

InfoBox> Name |E-mail |Телефон |Веб-сайт

Проблема, с которой я сталкиваюсь, заключается в том, как я пытаюсь записать данные в этой строке ниже

writer.writeAll((Iterable<String[]>) infoArray);

Это работает неправильно и ошибки, но я хотел показать, кто явроде после, и если есть кто-то, кто знаком с записью данных из Jsoup Elements в CSV. Спасибо

String filePath ="c:/results.csv";
                // first create file object for file placed at location
                // specified by filepath
                File file = new File(filePath);
                try {
                    // create FileWriter object with file as parameter
                    FileWriter outputfile = new FileWriter(file);

                    // create CSVWriter object filewriter object as parameter
                    CSVWriter writer = new CSVWriter(outputfile);

                    String[] header = { "Name", "Phone", "Street","State","City","Zipcode" };
                    Elements infobox = doc.select(".info");
                    List<String> infoArray = new ArrayList<>();

                    for(int i = 0; i < infobox.size(); i++){

                        infobox.get(i).select(".business-name > span");

                        infoArray.add(infobox.get(i).select(".business-name > span").text());
                        infoArray.add(infobox.get(i).select(".phones.phone.primary").text());
                        infoArray.add(infobox.get(i).select(".street-address").text());
                        infoArray.add(infobox.get(i).select(".state").text());
                        infoArray.add(infobox.get(i).select(".city").text());
                        infoArray.add(infobox.get(i).select(".zip").text());


                    }


                    writer.writeNext(header);
                    //How to write data in order to match each record accordingly?
                    //Data should be written to CSV like the following example under each header into each corrosponding row
                    //name, phone, street
                    writer.writeAll((Iterable<String[]>) infoArray);
                    for(String ia : infoArray){


                    }

                    // closing writer connection
                    writer.close();
                }
                catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

Ответы [ 2 ]

1 голос
/ 09 октября 2019

Вот что у меня получилось. Проблема не заключалась в добавлении строк в массив строк для передачи в CSVWriter. Вот мой пример.

   try {


                    String[] header = { "Name", "Phone", "Street","State","City","Zipcode" };
                    Elements infobox = doc.select(".info");

                    if(count == 0){

                        writer.writeNext(header);
                    }

                    for(int i = 0; i < infobox.size(); i++){



                        infobox.get(i).select(".business-name > span");

                        String businessName = infobox.get(i).select(".business-name > span").text();
                        String phone = infobox.get(i).select(".phones.phone.primary").text();
                        String address = infobox.get(i).select(".street-address").text();
                        //Address seems to be displayed another way too
                        String address2 = infobox.get(i).select(".adr").text();
                        //Use regular expression to normalize data


                        String[] columns = new String[]{
                                businessName, phone, address
                        };

                        writer.writeNext(columns);


                    }

                    writer.close();
                }
0 голосов
/ 11 октября 2019

Вот небольшой пример использования OpenCSV. Может быть, будет полезно для вас.

HeaderNames.java

public class HeaderNames
{

    public static final String NAME = "Name";
    public static final String PHONE = "Phone";
    public static final String STREET = "Street";
    public static final String STATE = "State";
    public static final String CITY = "City";
    public static final String ZIPCODE = "Zipcode";
}

DemoDTO.java

import java.io.Serializable;
import com.opencsv.bean.CsvBindByName;


public class DemoDTO implements Serializable
{

    private static final long serialVersionUID = 1L;

    @CsvBindByName(column = HeaderNames.NAME)
    private String name;

    @CsvBindByName(column = HeaderNames.PHONE)
    private String phone;

    @CsvBindByName(column = HeaderNames.STREET)
    private String street;

    @CsvBindByName(column = HeaderNames.STATE)
    private String state;

    @CsvBindByName(column = HeaderNames.CITY)
    private String city;

    @CsvBindByName(column = HeaderNames.ZIPCODE)
    private String zipcode;

    public String getName()
    {

    return name;
    }


    public void setName(String name)
    {

    this.name = name;
    }


    public String getPhone()
    {

    return phone;
    }


    public void setPhone(String phone)
    {

    this.phone = phone;
    }


    public String getStreet()
    {

    return street;
    }


    public void setStreet(String street)
    {

    this.street = street;
    }


    public String getState()
    {

    return state;
    }


    public void setState(String state)
    {

    this.state = state;
    }


    public String getCity()
    {

    return city;
    }


    public void setCity(String city)
    {

    this.city = city;
    }


    public String getZipcode()
    {

    return zipcode;
    }


    public void setZipcode(String zipcode)
    {

    this.zipcode = zipcode;
    }

}

Main.java

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.opencsv.CSVWriter;
import com.opencsv.bean.HeaderColumnNameMappingStrategy;
import com.opencsv.bean.StatefulBeanToCsv;
import com.opencsv.bean.StatefulBeanToCsvBuilder;
import com.opencsv.exceptions.CsvDataTypeMismatchException;
import com.opencsv.exceptions.CsvRequiredFieldEmptyException;


public class Main
{

    public static void main(String[] args) throws IOException, CsvDataTypeMismatchException, CsvRequiredFieldEmptyException
    {

    File file = new File(System.getProperty("user.dir") + System.getProperty("file.separator") + "results.csv");

    FileWriter writer = new FileWriter(file);

    List<DemoDTO> beans = new ArrayList<DemoDTO>();

    for (int i = 0; i < 10; i++)
    {
        DemoDTO demoDTO = new DemoDTO();

        demoDTO.setCity("city " + i);
        demoDTO.setName("name " + i);
        demoDTO.setPhone("phone " + i);
        demoDTO.setState("state " + i);
        demoDTO.setStreet("street " + i);
        demoDTO.setZipcode("zipcode " + i);

        beans.add(demoDTO);
    }

    HeaderColumnNameMappingStrategy<DemoDTO> strategy = new HeaderColumnNameMappingStrategy<>();
    strategy.setType(DemoDTO.class);

    StatefulBeanToCsv<DemoDTO> beanToCsv = new StatefulBeanToCsvBuilder<DemoDTO>(writer)
        .withSeparator(';')
        .withEscapechar(CSVWriter.NO_ESCAPE_CHARACTER)
        .withLineEnd(CSVWriter.DEFAULT_LINE_END)
        .withQuotechar(CSVWriter.DEFAULT_QUOTE_CHARACTER)
        .withMappingStrategy(strategy)
        .withThrowExceptions(true)
        .build();

    beanToCsv.write(beans);

    writer.flush();
    writer.close();
    }

}
...