0

ナビゲーションに問題があります。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;
        }
    }
4

1 に答える 1

1

問題は、(この場合は.Click()を使用して)新しいページに移動すると、キャッシュされた要素が無効になることです。DOMは、ブラウザの履歴に戻ったときを含め、ページが読み込まれるたびに再構築されます。したがって、既に移動したページをロードしている場合でも、新しく構築されたDOMを取得しているため、以前に構築されたDOMへのすべての参照は無効です。解決策は、前のページに戻った後、探している要素を再検索することです。

于 2012-09-03T15:35:31.953 に答える