Начал изучать парсинг. Написал код который парсит данные от сайта и записывает его.
Но возникла проблема. При парсинге значение Вылет (ЕТ) от сайта, у некоторых по ссылке значение Вылет (ЕТ) не выводиться. А вместе этого выходить то что я написал (Нет данных) или парситься другое значение. Скажите как могу решить эту проблему чтобы при парсинге по всех ссылок у меня выходило нужные значение Вылет (ЕТ).
(p.s. Я только начал и не в курсе где возникла проблема. Буду рад советам как еще могу улучить свой код для парсинга.)
package org.example;
import com.opencsv.CSVWriter;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.jsoup.HttpStatusException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) throws IOException {
Set<String> visitedUrls = new HashSet<>();
List<String> allLinks = new ArrayList<>();
List<String> errorLinks = new ArrayList<>();
String baseUrl = "https://altraauto.kz/almaty/diski?page=";
int totalPages = 112;
for (int page = 1; page <= totalPages; page++) {
String nextPageUrl = baseUrl + page;
if (visitedUrls.contains(nextPageUrl)) {
System.out.println("Страница уже была пропарсена. Пропускаем: " + nextPageUrl);
continue;
}
visitedUrls.add(nextPageUrl);
Document doc = Jsoup.connect(nextPageUrl).get();
Elements elements = doc.select("#pjax-container > div.list-view > div > div > div.product_real > div.product_initial > div.product_img > div > button[data-url]");
System.out.println("Количество найденных элементов: " + elements.size());
for (Element element : elements) {
String href = element.attr("data-url");
allLinks.add(href);
}
}
parseDataFromLinks(allLinks, errorLinks); // Вызов метода для парсинга данных
// Запись ошибочных ссылок и сообщений об ошибке в файл CSV
String csvFilePath = "errors.csv";
try (CSVWriter writer = new CSVWriter(new FileWriter(csvFilePath))) {
// Запись заголовка
String[] header = {"Ссылка", "Ошибка"};
writer.writeNext(header);
// Запись данных
for (String link : errorLinks) {
String[] data = {link, "Ошибка 404"};
writer.writeNext(data);
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Парсинг закончился.");
System.out.println("Всего парсировано страниц: " + visitedUrls.size());
System.out.println("Всего пропарсено ссылок: " + allLinks.size());
System.out.println("Всего ссылок с ошибкой 404: " + errorLinks.size());
}
private static void parseDataFromLinks(List<String> links, List<String> errorLinks) throws IOException {
String excelFilePath = "ResultParsing.xlsx";
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("Data");
// Создание заголовков столбцов
Row headerRow = sheet.createRow(0);
headerRow.createCell(0).setCellValue("Ссылка");
headerRow.createCell(1).setCellValue("Имя");
headerRow.createCell(2).setCellValue("Цена");
headerRow.createCell(3).setCellValue("Диаметр");
headerRow.createCell(4).setCellValue("Ширина диска");
headerRow.createCell(5).setCellValue("PCD");
headerRow.createCell(6).setCellValue("Вылет (ET)");
headerRow.createCell(7).setCellValue("DIA");
headerRow.createCell(8).setCellValue("Ошибка");
int rowNum = 1;
// Переменная для отслеживания времени последнего запроса
long lastRequestTime = 0;
for (String link : links) {
try {
Document doc = Jsoup.connect(link).get();
Element nameElement = doc.selectFirst("#tyre-product > div.product-wrapper._top > div > div._title > h1");
String name = nameElement.text();
Element priceElement = doc.selectFirst("#pjax-product-card > div > div > div:nth-child(1) > div.product_cart_price > span:nth-child(1)");
String price = (priceElement != null) ? priceElement.text() : "";
Element diameterElement1 = doc.selectFirst("#tyre-product > div:nth-child(3) > div > div._product-desc > div._parameter > ul > li:nth-child(1) > span:nth-child(2)");
String diameter = (diameterElement1 != null) ? diameterElement1.text() : "";
if (!diameter.isEmpty()) {
if (diameter.matches("\\d+")) {
// Значение состоит только из цифр
// Оставляем значение без изменений
} else {
// Значение содержит текст
diameter = "Нет данных";
}
} else {
diameter = "Нет данных";
}
Element widthElement1 = doc.selectFirst("li > span:nth-child(2)");
String width = (widthElement1 != null) ? widthElement1.text() : "";
if (!width.isEmpty()) {
if (width.matches("\\d+")) {
// Значение состоит только из цифр
// Оставляем значение без изменений
} else {
// Значение содержит текст
width = "Нет данных";
}
} else {
width = "Нет данных";
}
Element pcdElement = doc.selectFirst("li > span:nth-child(2)");
String pcd = (pcdElement != null) ? pcdElement.text() : "";
if (!pcd.isEmpty()) {
if (pcd.matches("\\d+")) {
// Значение состоит только из цифр
// Оставляем значение без изменений
} else {
// Значение содержит текст
pcd = "Нет данных";
}
} else {
pcd = "Нет данных";
}
Element offsetElement = doc.select("ul > li > span:containsOwn(Вылет (ET)) + span").first();
String offset = (offsetElement != null) ? offsetElement.text() : "Нет данных";
String diaRegex = "[+-]?\\d+";
Pattern diaPattern = Pattern.compile(diaRegex);
Matcher diaMatcher = diaPattern.matcher(diameter);
String dia = "";
if (diaMatcher.find()) {
dia = diaMatcher.group();
// Use the extracted value of "DIA"
} else {
dia = "Нет данных";
}
// Создание строки и запись данных в ячейки
Row row = sheet.createRow(rowNum++);
row.createCell(0).setCellValue(link);
row.createCell(1).setCellValue(name);
row.createCell(2).setCellValue(price);
row.createCell(3).setCellValue(diameter);
row.createCell(4).setCellValue(width);
row.createCell(5).setCellValue(pcd);
row.createCell(6).setCellValue(et);
row.createCell(7).setCellValue(dia);
} catch (HttpStatusException e) {
// Обработка ошибки 404
errorLinks.add(link);
Row row = sheet.createRow(rowNum++);
row.createCell(0).setCellValue(link);
row.createCell(8).setCellValue("Ошибка 404");
}
}
// Автоматическое изменение ширины столбцов
for (int i = 0; i < 10; i++) {
sheet.autoSizeColumn(i);
}
// Запись данных в файл Excel
try (FileOutputStream outputStream = new FileOutputStream(excelFilePath)) {
workbook.write(outputStream);
}
workbook.close();
System.out.println("Данные успешно записаны в файл: " + excelFilePath);
// Переменная для отслеживания времени последнего запроса
//
// Цикл для выполнения запросов
for (int i = 0; i < 2; i++) {
// Выполняем запрос и обрабатываем полученные данные
// Рассчитываем время, прошедшее с момента последнего запроса
long currentTime = System.currentTimeMillis();
long timeElapsed = currentTime - lastRequestTime;
// Вычисляем задержку (delay) в миллисекундах, чтобы выполнить 2 запроса в секунду
long delay = 3000 - timeElapsed; // 3000 milliseconds = 3 seconds
// Если прошло меньше 3000 миллисекунд с предыдущего запроса, ждем оставшееся время
if (delay > 0) {
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// Обновляем время последнего запроса
lastRequestTime = System.currentTimeMillis();
}
}
}