使用Selenium携带Payload请求时触发ArgumentNullException异常
问题
尝试使用Selenium绕过CloudFlare保护,成功访问首页并绕过验证后,从首页提取ViewState、ViewStateGuid等参数,携带请求参数再次发起请求时出现以下错误。
代码实现
val url = "https:abc.com" val searchPageUrl = "abc.com?" System.setProperty("webdriver.chrome.driver", "/home/asif/Downloads/chromedriver_linux64/chromedriver") val chromeOptions = new ChromeOptions() chromeOptions.addArguments("--remote-allow-origins=*") chromeOptions.setCapability("javascriptEnabled", true) chromeOptions.setCapability("acceptSslCerts", true) val driver = new ChromeDriver(chromeOptions) driver.get(url) val html = driver.getPageSource val browser = new JsoupBrowser() val homePageDoc = browser.parseString(html) val __VIEWSTATEGUID = homePageDoc >> element("input[name='__VIEWSTATEGUID']") >> attr("value") val __EVENTTARGET = homePageDoc >> element("input[name='__EVENTTARGET']") >> attr("value") val ScriptManager1_TSM = homePageDoc >> element("input[name='ScriptManager1_TSM']") >> attr("value") val __LASTFOCUS = homePageDoc >> element("input[name='__LASTFOCUS']") >> attr("value") val __VIEWSTATE = homePageDoc >> element("input[name='__VIEWSTATE']") >> attr("value") val __EVENTARGUMENT = homePageDoc >> element("input[name='__EVENTARGUMENT']") >> attr("value") val formData = Map( "ScriptManager1_TSM" -> ScriptManager1_TSM, "__EVENTTARGET" -> __EVENTTARGET, "__EVENTARGUMENT" -> __EVENTARGUMENT, "__LASTFOCUS" -> __LASTFOCUS, "__VIEWSTATEGUID" -> __VIEWSTATEGUID, "__VIEWSTATE" -> __VIEWSTATE, "__SCROLLPOSITIONX" -> "12", "__SCROLLPOSITIONY" -> "310", "ctl00$MainContent$LastNameTextBox" -> "eli", "ctl00$MainContent$FirstNameTextBox" -> "", "ctl00$MainContent$MiddleInitialTextBox" -> "", "ctl00$MainContent$NotaryIdTextBox" -> "", "ctl00$MainContent$BusinessNameTextBox" -> "", "ctl00$MainContent$ZipCodeTextBox" -> "", "ctl00$MainContent$CountyCombo" -> "", "ctl00$MainContent$ActiveNotariesCheckBox" -> "", "ctl00$MainContent$SearchButton" -> "Search" ) val formDataString = formData.map { case (key, value) => s"$key=${java.net.URLEncoder.encode(value, "UTF-8")}" }.mkString("&") val postBody = formDataString val searchPageDriver = new ChromeDriver(chromeOptions) searchPageDriver.get(searchPageUrl + postBody) val html1 = searchPageDriver.getPageSource val doc = browser.parseString(html1) println(doc) driver.close() searchPageDriver.close()
错误信息
描述:执行当前Web请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误的更多信息及其在代码中的起源位置。
[ArgumentNullException: 值不能为 null。
参数名称: inputString]
System.Web.UI.ObjectStateFormatter.Deserialize(String inputString, Purpose purpose) +684
System.Web.UI.ObjectStateFormatter.System.Web.UI.IStateFormatter.Deserialize(String serializedState) +49
DatabasePageStatePersister.Load() 在 \ad.local\shares\Web\Webdata\websites\apps.azsos.gov\apps\notary\search\App_Code\DatabasePageStatePersister.cs:64
System.Web.UI.Page.LoadPageStateFromPersistenceMedium() +58
System.Web.UI.Page.LoadAllState() +46
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +859
解决方案
1. 复用同一个浏览器会话
你创建了两个独立的ChromeDriver实例,第二个实例没有继承第一个的CloudFlare验证会话、ASP.NET会话Cookie,导致服务器无法识别请求,状态参数失效。直接复用第一个driver即可:
// 移除第二个ChromeDriver实例的创建代码,直接在原driver上操作 // 模拟填写表单后点击搜索按钮 driver.findElement(By.id("ctl00_MainContent_LastNameTextBox")).sendKeys("eli") driver.findElement(By.id("ctl00_MainContent_SearchButton")).click() // 等待页面加载完成后获取源码 val html1 = driver.getPageSource val doc = browser.parseString(html1) println(doc) driver.close()
2. 避免手动拼接参数,直接模拟用户操作
ASP.NET WebForms的状态参数(如__VIEWSTATE)和会话绑定,手动拼接参数并通过GET提交不符合规范,容易导致参数失效。直接用Selenium模拟填写表单、点击按钮的操作,让浏览器自动处理表单提交和参数传递,可靠性更高。
3. 确保状态参数正确获取
用Jsoup解析页面源码可能无法正确获取动态生成的元素,改用Selenium原生的findElement方法获取参数更可靠,同时添加等待机制确保元素加载完成:
import org.openqa.selenium.support.ui.WebDriverWait import org.openqa.selenium.support.ui.ExpectedConditions val wait = new WebDriverWait(driver, java.time.Duration.ofSeconds(10)) // 等待__VIEWSTATE元素加载完成 val viewState = wait.until(ExpectedConditions.presenceOfElementLocated(By.name("__VIEWSTATE"))).getAttribute("value") // 同理获取其他参数 val viewStateGuid = wait.until(ExpectedConditions.presenceOfElementLocated(By.name("__VIEWSTATEGUID"))).getAttribute("value")
4. 检查参数是否为null
在获取参数后打印日志,确认没有null值。如果某个参数为null,说明页面元素未正确加载,需要调整等待时间或元素定位方式。
内容的提问来源于stack exchange,提问作者user21236160

