Добавлен парсер атвомобилей
This commit is contained in:
145
Helpers/CarParser.cs
Normal file
145
Helpers/CarParser.cs
Normal file
@@ -0,0 +1,145 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using OpenQA.Selenium;
|
||||
using OpenQA.Selenium.Firefox;
|
||||
using OpenQA.Selenium.Support.UI;
|
||||
|
||||
namespace GtaVUsersInfo.Helpers
|
||||
{
|
||||
public class Car
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public int Price { get; set; }
|
||||
public string Photo { get; set; }
|
||||
public string Manufacturer { get; set; }
|
||||
public string Class { get; set; }
|
||||
public string Model { get; set; }
|
||||
}
|
||||
|
||||
public class CarParser : IDisposable
|
||||
{
|
||||
private IWebDriver driver;
|
||||
|
||||
public CarParser()
|
||||
{
|
||||
var chromeOptions = new FirefoxOptions();
|
||||
chromeOptions.AddArgument("--no-sandbox");
|
||||
driver = new FirefoxDriver(chromeOptions);
|
||||
}
|
||||
|
||||
public async Task<List<Car>> ParseCarsFromPages(int maxPages)
|
||||
{
|
||||
var cars = new List<Car>();
|
||||
for (int page = 1; page <= maxPages; page++)
|
||||
{
|
||||
var url = $"https://gtacars.net/?page={page}";
|
||||
var pageCars = await ParseCarsFromPage(url);
|
||||
cars.AddRange(pageCars);
|
||||
}
|
||||
return cars;
|
||||
}
|
||||
|
||||
private async Task<List<Car>> ParseCarsFromPage(string url)
|
||||
{
|
||||
var cars = new List<Car>();
|
||||
|
||||
// Открываем страницу в браузере
|
||||
driver.Navigate().GoToUrl(url);
|
||||
|
||||
// Ожидание, пока динамические элементы не подгрузятся
|
||||
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(60));
|
||||
// Ждём, пока появится хотя бы один элемент с ценой
|
||||
wait.Until(drv => drv.FindElements(By.CssSelector("span.v-popper--has-tooltip")).Any(e => e.Text.Contains("$")));
|
||||
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
|
||||
Thread.Sleep(100);
|
||||
js.ExecuteScript("window.scrollTo(0, document.body.scrollHeight / 4);");
|
||||
Thread.Sleep(100);
|
||||
js.ExecuteScript("window.scrollTo(0, document.body.scrollHeight / 3);");
|
||||
Thread.Sleep(100);
|
||||
js.ExecuteScript("window.scrollTo(0, document.body.scrollHeight / 2);");
|
||||
Thread.Sleep(100);
|
||||
js.ExecuteScript("window.scrollTo(0, document.body.scrollHeight);");
|
||||
Thread.Sleep(500);
|
||||
|
||||
wait.Until(drv => drv.FindElements(By.CssSelector("img[src*='data:image/gif']")).Count == 0);
|
||||
|
||||
// После этого можно парсить элементы
|
||||
var carElements = driver.FindElements(By.CssSelector("div.relative.flex.flex-col"));
|
||||
foreach (var carElement in carElements)
|
||||
{
|
||||
var car = new Car();
|
||||
|
||||
// Имя автомобиля
|
||||
var nameElement = carElement.FindElement(By.CssSelector("span[title]"));
|
||||
car.Name = nameElement.Text;
|
||||
|
||||
// Цена автомобиля
|
||||
var priceElement = carElement.FindElement(By.CssSelector("span.v-popper--has-tooltip"));
|
||||
var priceText = priceElement.Text;
|
||||
car.Price = ParsePrice(priceText);
|
||||
|
||||
// Фото
|
||||
var photoElement = carElement.FindElement(By.CssSelector("img.w-full"));
|
||||
car.Photo = photoElement.GetAttribute("src");
|
||||
|
||||
// Производитель
|
||||
var manufacturerElement = carElement.FindElement(By.CssSelector("a[href*='filter_manufacturer']"));
|
||||
car.Manufacturer = manufacturerElement.Text;
|
||||
|
||||
// Класс автомобиля
|
||||
var classElement = carElement.FindElement(By.CssSelector("a[href*='filter_class']"));
|
||||
car.Class = classElement.Text;
|
||||
|
||||
// Модель (часть URL)
|
||||
var modelElement = carElement.FindElement(By.CssSelector("a[href]"));
|
||||
car.Model = modelElement.GetAttribute("href").Split('/').Last();
|
||||
|
||||
cars.Add(car);
|
||||
}
|
||||
|
||||
return cars;
|
||||
}
|
||||
|
||||
|
||||
private int ParsePrice(string priceText)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(priceText)) return 0;
|
||||
priceText = priceText.Replace("$", "").Replace(",", "").Replace(" ", "");
|
||||
return int.TryParse(priceText, out int price) ? price : 0;
|
||||
}
|
||||
|
||||
public void SaveToJson(List<Car> cars, string filePath)
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(cars, Formatting.Indented);
|
||||
File.WriteAllText(filePath, json);
|
||||
}
|
||||
|
||||
// Реализация метода Dispose
|
||||
public void Dispose()
|
||||
{
|
||||
if (driver != null)
|
||||
{
|
||||
driver.Quit();
|
||||
driver.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Program
|
||||
{
|
||||
static async Task Main(string[] args)
|
||||
{
|
||||
using (var parser = new CarParser())
|
||||
{
|
||||
var cars = await parser.ParseCarsFromPages(25);
|
||||
parser.SaveToJson(cars, "cars.json");
|
||||
Console.WriteLine("Data saved to cars.json");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
13
Helpers/Strings.cs
Normal file
13
Helpers/Strings.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace GtaVUsersInfo.Helpers
|
||||
{
|
||||
public class Strings
|
||||
{
|
||||
public readonly static string carUrl = "https://gtacars.net/";
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user