当我在示例代码中按下表单上的停止按钮时,driver.Quit()调用会抛出NullReference异常,但是当我将它悬停在IDE中的对象上,当它在异常中断时,该对象不是空。
此外,在null检查条件下调用driver.Quit()。
public partial class ProxyScraperForm : Form
{
private BindingList<IProxyScraperSite> sites = new BindingList<IProxyScraperSite>();
private List<IWebDriver> activeDrivers = new List<IWebDriver>();
public BindingList<IProxyScraperSite> Sites { get { return this.sites; } }
public ProxyScraperForm()
{
InitializeComponent();
sites.Add(new ProxyScraperSiteUsProxyOrg());
sites.Add(new ProxyScraperSiteFreeProxyListNet());
sites.Add(new ProxyScraperSiteFreeProxyListsNet());
sites.Add(new ProxyScraperSiteHideMyName());
sites.Add(new ProxyScraperSiteHidester());
scraperDataGridView.DataSource = sites;
}
private void scrapeButton_Click(object sender, EventArgs e)
{
foreach (var site in sites)
{
Task.Run(async () =>
{
var driver = SeleniumUtility.CreateDefaultFirefoxDriver();
activeDrivers.Add(driver);
await site.ScrapeAsync(driver);
driver.Quit();
activeDrivers.Remove(driver);
});
}
}
private void stopButton_Click(object sender, EventArgs e)
{
foreach (var driver in activeDrivers)
{
if (driver != null)
{
driver.Quit();
}
}
activeDrivers.Clear();
foreach (var site in sites)
{
site.Status = "Idle";
}
}
private void proxyScraperForm_FormClosing(object sender, FormClosingEventArgs e)
{
stopButton.PerformClick();
this.DialogResult = DialogResult.Cancel;
}
}
Inside site.ScrapeAsync
public class ProxyScraperSiteHideMyName : ProxyScraperSiteBase
{
public ProxyScraperSiteHideMyName() { SiteName = "HideMyName"; }
public override Task ScrapeAsync(IWebDriver driver, PauseOrCancelToken pct = null)
{
return Task.Run(async () =>
{
try
{
Status = "Starting";
driver.Navigate().GoToUrl("https://hidemy.name/en/proxy-list/");
var wait = new WebDriverWait(driver, new TimeSpan(0, 0, 30));
var lastPageLinkElement = wait.Until(extras.ExpectedConditions.ElementIsVisible((By.XPath("/html/body/div[1]/div/section[1]/div/div[4]/ul/li[10]/a"))));
var totalPages = Int32.Parse(lastPageLinkElement.Text);
for (int i = 0; i < totalPages; i++)
{
Status = $"Scraping page {i + 1} of {totalPages}";
var mc = Regex.Matches(driver.PageSource, RegexUtility.IPv4AndPortWithSeperatorRegexString);
foreach (Match m in mc)
{
try
{
var proxy = new Proxy(m.Groups[1].Value + m.Groups[2].Value);
OnProxyScraped(proxy);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex); ;
}
}
if (pct != null) { await pct.PauseOrCancelIfRequested(); }
if (i < totalPages - 1)
{
var nextButton = wait.Until(extras.ExpectedConditions.ElementToBeClickable(By.XPath("//li[@class='arrow__right']/a")));
nextButton.Click();
}
}
Status = "Completed!";
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex);
}
});
}
}
堆栈跟踪。
at OpenQA.Selenium.DriverService.Stop()
at OpenQA.Selenium.DriverService.Dispose(Boolean disposing)
at OpenQA.Selenium.Remote.DriverServiceCommandExecutor.Dispose(Boolean disposing)
at OpenQA.Selenium.Remote.DriverServiceCommandExecutor.Execute(Command commandToExecute)
at OpenQA.Selenium.Remote.RemoteWebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)
at OpenQA.Selenium.Remote.RemoteWebDriver.Dispose(Boolean disposing)
at OpenQA.Selenium.Remote.RemoteWebDriver.Quit()
at HelperLib.ProxyLib.Scraping.ProxyScraperForm.stopButton_Click(Object sender, EventArgs e) in C:\Users\david\source\repos\HelperLib\HelperLib\ProxyLib\Scraping\ProxyScraperForm.cs:line 55
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.RunDialog(Form form)
at System.Windows.Forms.Form.ShowDialog(IWin32Window owner)
at System.Windows.Forms.Form.ShowDialog()
at HelperLib.ProxyLib.Testing.proxyTesterView.AddFromScraperToolStripMenuItem_Click(Object sender, EventArgs e) in C:\Users\david\source\repos\HelperLib\HelperLib\ProxyLib\Testing\ProxyTesterView.cs:line 127
at System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e)
at System.Windows.Forms.ToolStripMenuItem.OnClick(EventArgs e)
at System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e)
at System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e)
at System.Windows.Forms.ToolStripItem.FireEventInteractive(EventArgs e, ToolStripItemEventType met)
at System.Windows.Forms.ToolStripItem.FireEvent(EventArgs e, ToolStripItemEventType met)
at System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea)
at System.Windows.Forms.ToolStripDropDown.OnMouseUp(MouseEventArgs mea)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.ToolStrip.WndProc(Message& m)
at System.Windows.Forms.ToolStripDropDown.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at TestingApp.Program.Main() in C:\Users\david\source\repos\TestingApp\TestingApp\Program.cs:line 19
答案 0 :(得分:0)
这是我的硒测试代码,希望它可以帮到你
var tasks = new List<Task>
{
new Task(PickUserFirefox)
};
tasks.ForEach(
task => task.Start()
);
Task.WaitAll(tasks.ToArray());
}
private static void PickUserFirefox()
{
FirefoxTesting(StaticRandom.Instance.Next(1000,9999), "abcd");
}
private static void FirefoxTesting(int id, string fileIds)
{
System.Environment.SetEnvironmentVariable("webdriver.gecko.driver", @"D:\Work\Testing\SelenimDriver\geckodriver.exe");
IWebDriver driver = new FirefoxDriver();
driver.Navigate().GoToUrl(URL + id + "/" + fileIds);
Thread.Sleep(1000);
try
{
//Do something here
}
catch (Exception e)
{
//Error handle here
}
Thread.Sleep(1000);
IWebElement btn = driver.FindElement(By.Id("btnSubmit"));
btn.Click();
Thread.Sleep(1000);
//driver.Close();
driver.Quit();
}
答案 1 :(得分:0)
通过使用ConcurrentDictionary并在lock语句中包装driver.Quit()来解决。
public partial class ProxyScraperForm : Form
{
private BindingList<IProxyScraperSite> sites = new BindingList<IProxyScraperSite>();
private ConcurrentDictionary<string, FirefoxDriver> activeDrivers = new ConcurrentDictionary<string, FirefoxDriver>();
private object lockObj = new object();
public BindingList<IProxyScraperSite> Sites { get { return this.sites; } }
public ProxyScraperForm()
{
InitializeComponent();
sites.Add(new ProxyScraperSiteUsProxyOrg());
sites.Add(new ProxyScraperSiteFreeProxyListNet());
sites.Add(new ProxyScraperSiteFreeProxyListsNet());
sites.Add(new ProxyScraperSiteHideMyName());
sites.Add(new ProxyScraperSiteHidester());
scraperDataGridView.DataSource = sites;
}
private void scrapeButton_Click(object sender, EventArgs e)
{
foreach (var site in sites)
{
Task.Run(async () =>
{
var driver = SeleniumUtility.CreateDefaultFirefoxDriver();
activeDrivers.TryAdd(site.SiteName, driver);
await site.ScrapeAsync(driver);
lock (lockObj)
{
driver.Quit();
}
activeDrivers.TryRemove(site.SiteName, out driver);
});
}
}
private void stopButton_Click(object sender, EventArgs e)
{
foreach (var driver in activeDrivers)
{
lock (lockObj)
{
driver.Value.Quit();
}
}
activeDrivers.Clear();
foreach (var site in sites)
{
site.Status = "Idle";
}
}
private void proxyScraperForm_FormClosing(object sender, FormClosingEventArgs e)
{
stopButton.PerformClick();
this.DialogResult = DialogResult.Cancel;
}
}