簡體   English   中英

Selenium - 我怎樣才能刮掉這張桌子?

[英]Selenium - How can I scrape this table?

我希望從https://www.worldometers.info/coronavirus/中抓取數據,但似乎表格的trtd在各行中不斷變化。 到目前為止,我有下面的代碼,但它不起作用。

public ArrayList<Data>getAllData(){
        ArrayList<Data>allData = new ArrayList<Data>();
        try {
        Thread.sleep(10000);
        WebDriver browser = load();
        int row = browser.findElements(By.xpath("/html[1]/body[1]/div[3]/div[3]/div[1]/div[4]/div[1]/div[1]/table[1]/tbody[1]/tr")).size();
        int col = browser.findElements(By.xpath("/html[1]/body[1]/div[3]/div[3]/div[1]/div[4]/div[1]/div[1]/table[1]/tbody[1]/tr[1]/td")).size();
        for ( int i = 3; i < row; i++) {
            for ( int j = 1; j < col; j++) {
        Data data = new Data();
        data.setId(browser.findElement(By.xpath("/html[1]/body[1]/div[3]/div[3]/div[1]/div[4]/div[1]/div[1]/table[1]/tbody[1]/tr["+i+"]/td["+j+"]")).getText());
        data.setCountry(browser.findElement(By.xpath("/html[1]/body[1]/div[3]/div[3]/div[1]/div[4]/div[1]/div[1]/table[1]/tbody[1]/tr["+i+"]/td["+j+"]")).getText());
        data.setTotalCases(browser.findElement(By.xpath("/html[1]/body[1]/div[3]/div[3]/div[1]/div[4]/div[1]/div[1]/table[1]/tbody[1]/tr["+i+"]/td["+j+"]")).getText());
        data.setNewCases(browser.findElement(By.xpath("/html[1]/body[1]/div[3]/div[3]/div[1]/div[4]/div[1]/div[1]/table[1]/tbody[1]/tr["+i+"]/td["+j+"]")).getText());
        data.setTotalDeaths(browser.findElement(By.xpath("/html[1]/body[1]/div[3]/div[3]/div[1]/div[4]/div[1]/div[1]/table[1]/tbody[1]/tr["+i+"]/td["+j+"]")).getText());
        data.setNewDeaths(browser.findElement(By.xpath("/html[1]/body[1]/div[3]/div[3]/div[1]/div[4]/div[1]/div[1]/table[1]/tbody[1]/tr["+i+"]/td["+j+"]")).getText());
        data.setTotalRecovered(browser.findElement(By.xpath("/html[1]/body[1]/div[3]/div[3]/div[1]/div[4]/div[1]/div[1]/table[1]/tbody[1]/tr["+i+"]/td["+j+"]")).getText());
        data.setActiveCases(browser.findElement(By.xpath("/html[1]/body[1]/div[3]/div[3]/div[1]/div[4]/div[1]/div[1]/table[1]/tbody[1]/tr["+i+"]/td["+j+"]")).getText());
        data.setSeriousCases(browser.findElement(By.xpath("/html[1]/body[1]/div[3]/div[3]/div[1]/div[4]/div[1]/div[1]/table[1]/tbody[1]/tr["+i+"]/td["+j+"]")).getText());
        data.setTotalCasesPerMillionPop(browser.findElement(By.xpath("/html[1]/body[1]/div[3]/div[3]/div[1]/div[4]/div[1]/div[1]/table[1]/tbody[1]/tr["+i+"]/td["+j+"]")).getText());
        data.setTotalDeathsPerMillionPop(browser.findElement(By.xpath("/html[1]/body[1]/div[3]/div[3]/div[1]/div[4]/div[1]/div[1]/table[1]/tbody[1]/tr["+i+"]/td["+j+"]")).getText());
        data.setTotalTests(browser.findElement(By.xpath("/html[1]/body[1]/div[3]/div[3]/div[1]/div[4]/div[1]/div[1]/table[1]/tbody[1]/tr["+i+"]/td["+j+"]")).getText());
        data.setTestsPerMillion(browser.findElement(By.xpath("/html[1]/body[1]/div[3]/div[3]/div[1]/div[4]/div[1]/div[1]/table[1]/tbody[1]/tr["+i+"]/td["+j+"]")).getText());       
        allData.add(data);
            }
        }
        browser.quit();
        browser.close();
        }
        catch(Exception e) {
            e.printStackTrace();
        }
    
        return allData;
        }

您當前正在做的是查找與行和列匹配的所有元素 - 但隨后您正在導航表上的索引位置,而不是您找到的實際元素。

如果您查看開發工具中的表格主體,您可以看到它包含從視圖中隱藏的總行數。 USA 是第 3 行(在 devtools 中突出顯示),但第 4、5 和 6 行是總數。 開發工具

如果您展開,那么列號和內容會有所不同。

有幾點建議:

嘗試更智能的 xpath 來獲取所有行:(這似乎跳過了那些標題)

//table[@id="main_table_countries_today"]//tr[@role="row"]

然后,使用 foreach 循環迭代您找到的行元素(不是通過 xpath 索引)。 並且,在該循環內,獲取每行中的 td 標簽。

例如:

public void GettingAllTheData(){

            //Get all the ROWS that match
            var rows = driver.findElements(By.xpath("//table[@id='main_table_countries_today']//tr[@role='row']"));

            //loop all rows
            for (var row : rows) {
                //Then get the columns within the row object!
                var cols = row.findElements(By.tagName("td"));

                //replace this with writing out your data 
                //this is jut to make sure it writes out as expected. 
                //You might not need a second loop 
                for (var col : cols)
                {
                    System.out.println(col.getText());
                }
            }
    }

我不想重新創建您的數據 object 所以我只是打印。 對我來說,這似乎始終如一地寫出結果。

第一次迭代:

1
USA
3,619,643
+2,816
140,200
+56
1,646,683
1,832,760
16,459
10,933
423
44,867,389
135,518
331,081,677

第二次迭代:

2
Brazil
1,972,072
+1,163
75,568
+45
1,366,775
529,729
8,318
9,275
355
4,911,063
23,098
212,620,008

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM