ナビゲーションに問題があります。htmlテーブルから行のリストを取得します。行を繰り返し処理し、それらから情報を取得します。しかし、私がクリックしてスクレイプする行に関連する詳細情報に移動するための行にもリンクがあります。次に、元のテーブルのあるページに戻ります。これは最初の行では機能しますが、後続の行では例外がスローされます。
行内のリンクが最初にクリックされた後に行コレクションを確認しましたが、リンクをクリックする前のように正しい値を持っているものはありません。取得していない別のURLに移動すると、何かが起こっていると思います。
私のコードは以下の通りです。親テーブルを繰り返し処理し、各行のリンクをクリックして子テーブルに移動しながら、親テーブルの行を繰り返し処理できるようにするには、どうすればよいですか?
private List<Document> getResults()
{
var documents = new List<Document>();
//Results
IWebElement docsTable = this.webDriver.FindElements(By.TagName("table"))
.Where(table => table.Text.Contains("Document List"))
.FirstOrDefault();
var validDocRowRegex = new Regex(@"^(\d{3}\s+)");
var docRows = docsTable.FindElements(By.TagName("tr"))
.Where(row =>
//It throws an exception with .FindElement() when there isn't one.
row.FindElements(By.TagName("td")).FirstOrDefault() != null &&
//Yeah, I don't get this one either. I negate the match and so it works??
!validDocRowRegex.IsMatch(
row.FindElement(By.TagName("td")).Text))
.ToList();
foreach (var docRow in docRows)
{
//Todo: find out why this is crashing on some documents.
var cells = docRow.FindElements(By.TagName("td"));
var document = new Document
{
DocID = Convert.ToInt32(cells.First().Text),
PNum = Convert.ToInt32(cells[1].Text),
AuthNum = Convert.ToInt32(cells[2].Text)
};
//Go to history for the current document.
cells.Where(cell =>
cell.FindElements(By.TagName("a")).FirstOrDefault() != null)
.FirstOrDefault().Click();
//Todo: scrape child table.
this.webDriver.Navigate().Back();
}
return documents;
}
更新:(ジム・エバンスの回答に応えて)
これは正しく機能しているようです。
private List<Document> getResults()
{
var documents = new List<Document>();
IWebElement docRow = null;
int rowIndex = 0;
while((docRow = this.getDocumentRow(rowIndex)) != null)
{
var cells = docRow.FindElements(By.TagName("td"));
var document = new Document
{
DocID = Convert.ToInt32(cells.First().Text),
PNum = Convert.ToInt32(cells[1].Text),
AuthNum = Convert.ToInt32(cells[2].Text)
};
//Go to history for the current document.
cells.Where(cell =>
cell.FindElements(By.TagName("a")).FirstOrDefault() != null)
.FirstOrDefault().Click();
//Todo: scrape child table.
this.webDriver.Navigate().Back();
documents.Add(well);
rowIndex++;
}
return documents;
}
private IWebElement getDocumentRow(int rowIndex)
{
try
{
IWebElement docsTable = this.webDriver.FindElements(By.TagName("table"))
.Where(table => table.Text.Contains("Document List"))
.FirstOrDefault();
var validDocRowRegex = new Regex(@"^(\d{3}\s+)");
var docRow = docsTable.FindElements(By.TagName("tr"))
.Where(row =>
//It throws an exception with .FindElement() when there isn't one.
row.FindElements(By.TagName("td")).FirstOrDefault() != null &&
//Yeah, I don't get this one either. I negate the match and so it works??
!validDocRowRegex.IsMatch(
row.FindElement(By.TagName("td")).Text))
.ElementAt(rowIndex);
return docRow;
}
catch
{
return null;
}
}