I am pulling data from the website with Selenium according to the numbers I pulled from Excel to the datagridview. However, if a number cannot be found, the program gives an error and stops working. How can I make it skip numbers it can't find? My code block is as follows. Note: Link lines have been deleted for security purposes. Please ignore it.

drv.SwitchTo().Window(drv.WindowHandles.ToList().Last());
for (int i = 0; i < dataGridView1.Rows.Count - 1; i++)
{
var val0 = dataGridView1.Rows[i].Cells[0].Value.ToString();
drv.FindElement(By.Id("txtTC")).SendKeys(val0);
Thread.Sleep(3000);
drv.FindElement(By.Id("btnAra")).Click();
Thread.Sleep(3000);
if (val0 != null && val0 != string.Empty)
{
var val1 = drv.FindElement(By.Id("txtKisiTCKimlikNo")).GetAttribute("value"); // It gives error when val1 is not found.
var val2 = drv.FindElement(By.Id("txtAdi")).GetAttribute("value");
var val3 = drv.FindElement(By.Id("txtSoyadi")).GetAttribute("value");
dataGridView1.Rows[i].Cells[1].Value = val1;
dataGridView1.Rows[i].Cells[2].Value = val2;
dataGridView1.Rows[i].Cells[3].Value = val3;
drv.FindElement(By.XPath("/html/body/form[2]/table/tbody/tr[3]/td[1]/div/div/table/tbody/tr[7]/td/table/tbody/tr[2]/td/table[2]/tbody/tr[7]/td")).Click(); Thread.Sleep(3000);
var val4 = drv.FindElement(By.XPath("/html/body/form[2]/div[4]/div/div[3]/div/div/div[1]/div/div[4]/div/div[2]/div/div/div/div[2]/div/div/div[1]")).Text;
Thread.Sleep(3000);
var val5 = drv.FindElement(By.XPath("/html/body/form[2]/div[4]/div/div[3]/div/div/div[1]/div/div[4]/div/div[2]/div/div/div/div[3]/div/div/div[1]")).Text;
Thread.Sleep(3000);
var val6 = drv.FindElement(By.XPath("//div[9]/div/div/div/input")).GetAttribute("value");
Thread.Sleep(3000);
var val7 = drv.FindElement(By.XPath("/html/body/form[2]/div[4]/div/div[3]/div/div/div[1]/div/div[2]/div/div[2]/div/div/h4")).Text;
dataGridView1.Rows[i].Cells[4].Value = val4;
dataGridView1.Rows[i].Cells[5].Value = val5;
dataGridView1.Rows[i].Cells[6].Value = val6;
dataGridView1.Rows[i].Cells[7].Value = val7;
drv.FindElement(By.XPath("/html/body/form[2]/nav/div/div/div[2]/ul[2]/li[2]/ul/li[6]/a")).Click();
Thread.Sleep(3000);
var val8 = drv.FindElement(By.XPath("/html/body/form[2]/div[4]/div/div[3]/div/div/div[1]/div/div[4]/div/div[2]/div/div/div/div[2]/div/div/div[1]")).Text;
Thread.Sleep(3000);
var val9 = drv.FindElement(By.XPath("/html/body/form[2]/div[4]/div/div[3]/div/div/div[1]/div/div[4]/div/div[2]/div/div/div/div[3]/div/div/div[1]")).Text;
Thread.Sleep(3000);
var val10 = drv.FindElement(By.XPath("/html/body/form[2]/div[4]/div/div[3]/div/div/div[1]/div/div[4]/div/div[2]/div/div/div/div[9]/div/div/div/input")).GetAttribute("value");
Thread.Sleep(3000);
var val11 = drv.FindElement(By.XPath("/html/body/form[2]/div[4]/div/div[3]/div/div/div[1]/div/div[2]/div/div[2]/div/div/h4")).Text;
dataGridView1.Rows[i].Cells[8].Value = val8;
dataGridView1.Rows[i].Cells[9].Value = val9;
dataGridView1.Rows[i].Cells[10].Value = val10;
dataGridView1.Rows[i].Cells[11].Value = val11;
}
}
Tuhin PaulPosted Jan 6, 2024, 3:28 PM
In this modified code, I've changed the string.Empty check to !string.IsNullOrEmpty(val0) for better null handling. Additionally, I've added a continue statement after catching the NoSuchElementException to explicitly skip to the next iteration of the loop.
If the expected element is nested within another element that might not be present, the exception might be thrown at a different level. Adjust the locators or handle potential exceptions for those parent elements.
Mehmet FatihPosted Jan 6, 2024, 8:39 PM
Tuhin, first of all, thank you very much for your interest. I tried your modified code again. However, I regret to say that unfortunately it still does not skip numbers that are not available. For numbers that are not found, the program simply stops working.
Tuhin PaulPosted Jan 6, 2024, 3:30 PM
Talking about unit testing, it's a good practice to make your code more testable and modular. One way to achieve this is by introducing abstractions and dependency injection. In your case, you might want to introduce an interface or a delegate to represent the functionality of finding elements by specific identifiers. This allows you to create a mock or fake implementation for testing purposes.
Mehmet FatihPosted Jan 6, 2024, 9:49 AM
I tried the modified codes. However, this time it does not skip the number that cannot be found and continue with the next number.
Naimish MakwanaPosted Jan 6, 2024, 8:03 AM
You can use a
try-catchblock to handle the exception when a number cannot be found. This way, if an error occurs, the program will skip the current iteration and continue with the next one. Here’s how you can modify your code:In this code,
NoSuchElementExceptionis caught when an element cannot be found. The program will then print a message to the console and skip the current iteration of the loop with thecontinuestatement. You can replace theConsole.WriteLineline with any error handling or logging code that suits your needs. Please note that you need to importOpenQA.Seleniumto useNoSuchElementException. If there are other types of exceptions you want to catch, you can add morecatchblocks. Remember to always handle exceptions responsibly to avoid hiding errors that might need to be fixed.Thanks
Tuhin PaulPosted Jan 6, 2024, 7:47 AM
To handle the scenario where an element is not found and avoid the program from crashing, you can use try-catch blocks to catch exceptions. Specifically, in your case, you can use a try-catch block around the code that might throw an exception when an element is not found. If an exception is caught, you can set the corresponding cell value to some default value or leave it empty.
the FindElement method throws a NoSuchElementException (indicating the element wasn't found), the error is caught and the code can proceed. When the exception is caught, the continue statement skips the rest of the current iteration and moves to the next number in the loop, preventing the program from crashing. The Console.WriteLine statement within the catch block can be used to log or display a message indicating that a number was not found, aiding in debugging and tracking.
You should be using explicit waits (e.g., WebDriverWait in C#) instead of Thread.Sleep for more reliable element interaction and better performance.