Класс перевода Selenium работает неправильно С#

Я написал класс на С#, который открывает веб-сайт и переводит введенный текст. Этот класс использует селен, который я использую для всего проекта.

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

В чем проблема: большую часть времени этот класс работает отлично, однако, когда вы устанавливаете длинную строку в качестве входных данных, я получаю сообщение об ошибке OpenQA.Selenium.WebDriverException: 'target frame detached (Session info: chrome=102.0.5005.63). Это также происходит, когда интернет-соединение недостаточно стабильно (например, обычный Wi-Fi). Не могу понять, как запрограммировать, чтобы программа ждала перевода. Кто-нибудь решение?

Основной код

public MainWindow()
        {
            InitializeComponent();

            
            String[] franseZinnen = { "S’il vous plaît", "Je suis désolé", "Madame/Monsieur/Mademoiselle", "Excusez-moi", "Je ne comprends pas", "Je voudrais...", "Non, pas du tout", "Où sommes-nous?", "Pourriez-vous m’aider?", "Répétez s'il vous plaît.", "Où puis-je trouver un bon restaurant/café/la plage/le centre-ville?", "Je cherche cette adresse.", "J'ai besoin d'une chambre double..", "Je voudrais annuler ma réservation.", "Où est la boutique duty-free?", "Comment puis-je vous aider?", "Je cherche des chaussures.", "C’est combien?", "C’est trop cher!" };
            List<String> uitkomsten = new List<string>();

            String LangefranseTekst = "Temps ouais merde bière parce que du apéro. Vin vin croissant quelque manger. Quand même passer saucisson meilleur dans fromage quelque parce que.\r\nÀ la camembert boulangerie part omelette meilleur. Grève camembert fromage. Manger fois du coup carrément.\r\nEnée est juste le moyen de décorer l'oreiller de la vie. Duis eu tincidunt orci, de CNN. Tous mes besoins sont grands. Jusqu'à ce qu'il reçoive la messe et que l'urne flatte le laoreet. Proin reçoit beaucoup de rires. Suspendisse feugiat eros id risus vehicula lobortis. Vivamus ullamcorper orci a ligula pulvinar convallis.\r\nManger. Carrément guillotine saucisson épicé un apéro. Croissant boulangerie son du coup du coup moins quand même et paf le chien mais évidemment à révolution. À la du faire voila du coup. Évidemment entre et aussi voila.\r\nBaguette devoir camembert voila se disruptif disruptif et paf le chien se fais chier. Frenchtech se révolution monsieur du coup avec putain. Falloir disruptif grève comme même.\r\nVin omelette épicé. Comme même tout comme même. Peu camembert fromage parce que comme même voir ouais.\r\nDemander vin et aussi saucisson nous putain. De merde voila carrément et paf le chien il y a du coup aussi apéro.\r\nLe client est très important merci, le client sera suivi par le client. Énée n'a pas de justice, pas de résultat, pas de ligula, et la vallée veut la sauce. Morbi mais qui veut vendre une couche de contenu triste d'internet. Être ivre maintenant, mais ne pas être ivre maintenant, mon urne est d'une grande beauté, mais elle n'est pas aussi bien faite que dans un livre. Mécène dans la vallée de l'orc, dans l'élément même. Certaines des exigences faciles du budget, qu'il soit beaucoup de temps pour dignissim et. Je ne m'en fais pas chez moi, ça va être moche dans le vestibule. Mais aussi des protéines de Pour avant la fin de la semaine, qui connaît le poison, le résultat.";

            /*  // short translations
            foreach (var item in franseZinnen)
            {
                ChromeDriver driver = new ChromeDriver();
                String translation = vertalenNu.translateText(new ChromeDriver(), item, "fr", "en");
                uitkomsten.Add(translation);
                driver.Close(); 
            }*/

            // long translation
            ChromeDriver driver = new ChromeDriver();
            String translation = vertalenNu.translateText(new ChromeDriver(), LangefranseTekst, "fr", "en");
            uitkomsten.Add(translation);
            driver.Close();
            


            String stringVoorBreakpoint = "";

        }

Код в классе

[Serializable]
    public class vertalenNu
    {
        public static String translateText(IWebDriver driver, String text, String languageSource, String languageDestination)
        {
            // nl - en - de - fr -es -it
            driver.Url = "https://www.vertalen.nu/zinnen/";
            driver.FindElement(By.Id("vertaaltxt")).SendKeys(text);

            SelectElement testt = new SelectElement(driver.FindElement(By.Id("tselectfrom")));
            testt.SelectByValue(languageSource);

            SelectElement test = new SelectElement(driver.FindElement(By.Id("tselectto")));
            test.SelectByValue(languageDestination);

            driver.FindElement(By.XPath("//input[@title='Vertaal']")).Click();

            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(20));
            wait.Until(driver => driver.FindElement(By.ClassName("mt-translation-content")).Text != "");

            IWebElement technicalSheet = driver.FindElement(By.ClassName("mt-translation-content"));
            String technicalSheettext = technicalSheet.Text;

            driver.Close();
            driver.Quit();

            return technicalSheettext;

        }
    }

Мне кажется, вы получаете драйверы-сироты... почему бы просто не сделать это?: vertalenNu.translateText(driver, ... Вместо того, чтобы создавать два драйвера? Вы также должны использовать только .quit(). Не используйте close (), если у вас нет нескольких окон/вкладок и вы пытаетесь закрыть одну из них. Удалите вызовы driver.Close() и driver.Quit() в функции. Вызовите driver.quit(), когда закончите работу с Водитель.

pcalkins 10.11.2022 23:18

Я ценю предложения, и я изменил их. однако основная проблема, к сожалению, остается. Любое решение для этого?

Sebastiaan Maes 11.11.2022 00:08

Это исключение означает, что вы закрыли вкладку/окно, в котором в данный момент находится драйвер. (так что это в номансленде) Хотя для этого есть и другие причины, я бы внимательно посмотрел, сколько Chromedrivers и браузеров вы запускаете. (Должен быть только один...) И убедитесь, что у вас нет осиротевших процессов после .Quit(). (Проверьте диспетчер задач) Используйте одну ссылку на драйвер повсюду и используйте .Quit() только после того, как закончите.

pcalkins 11.11.2022 00:43

Кроме того, если вы создаете новый драйвер вскоре после закрытия одного из них, лучше включить сон между выходом из одного драйвера и созданием нового. Это даст драйверу/браузеру время на очистку. (временные папки и т. д.) Это поможет предотвратить бесхозные процессы драйвера. Вы также должны рассмотреть что-то более легкое, например драйвер HTMLUnit.

pcalkins 11.11.2022 23:50
Руководство для начинающих по веб-разработке на React.js
Руководство для начинающих по веб-разработке на React.js
Веб-разработка - это захватывающая и постоянно меняющаяся область, которая постоянно развивается благодаря новым технологиям и тенденциям. Одним из...
Разница между Angular и React
Разница между Angular и React
React и AngularJS - это два самых популярных фреймворка для веб-разработки. Оба фреймворка имеют свои уникальные особенности и преимущества, которые...
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Веб-скрейпинг, как мы все знаем, это дисциплина, которая развивается с течением времени. Появляются все более сложные средства борьбы с ботами, а...
Калькулятор CGPA 12 для семестра
Калькулятор CGPA 12 для семестра
Чтобы запустить этот код и рассчитать CGPA, необходимо сохранить код как HTML-файл, а затем открыть его в веб-браузере. Для этого выполните следующие...
ONLBest Online HTML CSS JAVASCRIPT Training In INDIA 2023
ONLBest Online HTML CSS JAVASCRIPT Training In INDIA 2023
О тренинге HTML JavaScript :HTML (язык гипертекстовой разметки) и CSS (каскадные таблицы стилей) - две основные технологии для создания веб-страниц....
Как собрать/развернуть часть вашего приложения Angular
Как собрать/развернуть часть вашего приложения Angular
Вам когда-нибудь требовалось собрать/развернуть только часть вашего приложения Angular или, возможно, скрыть некоторые маршруты в определенных средах?
0
4
68
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете попробовать это решение:

Сначала создайте класс, который будет обрабатывать переводы

public interface ITranslator : IDisposable
{
    void ClearInput();
    string Translate(string text);
}
public class Translator : ITranslator
{
    private const string Url = "https://www.vertalen.nu/zinnen/";
    private const int Timeout = 20;

    private By _source = By.Id("vertaaltxt");
    private By _destination = By.Id("resulttxt");
    private By _submit = By.XPath("//input[@type = 'submit']");

    private readonly WebDriverWait _wait;
    private readonly IWebDriver _driver;

    public Translator()
    {
        _driver = new ChromeDriver();
        _wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(Timeout));
        _driver.Navigate().GoToUrl(Url);
    }

    public string Translate(string text)
    {
        _driver.FindElement(_source).SendKeys(text);
        _driver.FindElement(_submit).Click();

        _ = _wait.Until(d => d.FindElement(_destination).Text.Length > 0);
        return _driver.FindElement(_destination).Text;
    }

    public void ClearInput()
    {
        _wait.Until(d => d.FindElement(_source)).Clear();
    }

    public void Dispose()
    {
        _driver.Dispose();
    }
}

В следующем примере основное внимание уделяется решению WinForms, но вы можете настроить его для любого приложения с пользовательским интерфейсом, которое вам нравится:

public partial class MainWindow : Form
{
    private readonly ITranslator _translator;
    private const int MaxChars = 1500;

    private int _currentCharsCount;

    public MainWindow()
    {
        InitializeComponent();
        _translator = new Translator();
    }

    private void translateBtn_Click(object sender, EventArgs e)
    {
        destinationTextBox.Text = _translator.Translate(sourceTextBox.Text);
        _translator.ClearInput();

        // or for better user experience use bellow code
        // if you decide to use this code don't forget to mark async this method

        //await Task.Run(() =>
        //{
        //    destinationTextBox.Text = _translator.Translate(sourceTextBox.Text);
        //    _translator.ClearInput();
        //});
    }

    private void MainWindow_FormClosing(object sender, FormClosingEventArgs e)
    {
        _translator.Dispose();
    }

    private void clickBtn_Click(object sender, EventArgs e)
    {
        sourceTextBox.Clear();
        destinationTextBox.Clear();
        charsCounter.Text = $"{MaxChars} characters remaining";
    }

    private void sourceTextBox_TextChanged(object sender, EventArgs e)
    {
        _currentCharsCount = MaxChars - sourceTextBox.TextLength;
        charsCounter.Text = $"{_currentCharsCount} characters remaining";
    }
}

Только что протестировал его с несколькими длинными текстовыми строками, и пока он работает отлично! Большое спасибо!

Sebastiaan Maes 13.11.2022 20:25

Я обновил код, чтобы интерфейс не зависал

ggeorge 14.11.2022 09:03

Другие вопросы по теме