【问题标题】:Struggling to scrape a table using selenium努力使用硒刮桌子
【发布时间】:2021-01-05 15:52:03
【问题描述】:

所以我很期待对这个link中出现的表格进行抓取。

为了刮,我决定使用硒。

在我的第一次尝试中,我所做的是:

driver = webdriver.Chrome(ChromeDriverManager().install())
driver.get(url)
html_source = self.driver.page_source
self.driver.quit()
BeautifulSoup(html_source, "html5lib")
table = soup.find('table', {'class': 'heavy-table ncpulse-fav-table ncpulse-sortable compressed-table'})
df = pd.read_html(str(table), flavor='html5lib', header=0, thousands='.', decimal=',')

但是它输出错误

'no tables found'

然后我尝试使用 expected_conditions 类,因为当我在 SO 中查找时,可能“页面源甚至在子元素完全呈现之前就被拉出”

因此我尝试了这样的事情:

driver.get(route)
element_present = expected_conditions.presence_of_element_located(
    (By.CLASS_NAME, 'heavy-table ncpulse-fav-table ncpulse-sortable compressed-table'))
WebDriverWait(driver, 20).until(element_present)
html_source = driver.page_source 
driver.quit()

但是这次它输出:

selenium.common.exceptions.TimeoutException: Message

因此我的问题是:我怎样才能获得所需的输出?我在使用 expected_conditions 类时做错了什么?到底是什么问题/前端技术让刮桌子变得如此困难?

【问题讨论】:

    标签: python selenium xpath css-selectors webdriverwait


    【解决方案1】:

    CLASSNAME 选择器不处理复合类名,但您可以通过 css 选择器或 xpath 获取它。 CSS_SELECTOR 比 XPATH 更高效

    element_present = expected_conditions.presence_of_element_located(
                (By.CSS_SELECTOR, "table[class='heavy-table ncpulse-fav-table ncpulse-sortable compressed-table']"))
        #or by xpath
    element_present = expected_conditions.presence_of_element_located(
                (By.XPATH, "//table[@class='heavy-table ncpulse-fav-table ncpulse-sortable compressed-table']"))
    

    【讨论】:

      【解决方案2】:

      对于多个类名,使用最右边。

      element_present = WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.CLASS_NAME, 'compressed-table')))
      print(element_present.text)
      

      输出

      AKTIE +/- +/-% SENESTE ÅTD% VOLUMEN OMSÆTNING MARKEDSVÆRDI
      Abn Amro Bank N.V. -0,32 -4,08% 7,48 -53,90% 7,9 mio 59,0 mio -
      Adyen 81,00 5,62% 1523,00 108% 954 082 1,5 mia -
      Aegon -0,08 -3,49% 2,16 -45,47% 17,4 mio 37,5 mio -
      Ahold Del 0,25 0,98% 25,65 19,74% 8,0 mio 204,1 mio -
      Akzo Nobel 0,14 0,16% 85,86 -3,16% 1,1 mio 90,6 mio -
      Arcelormittal Sa 0,08 0,66% 11,53 -26,26% 11,9 mio 137,3 mio -
      

      转成英文

      options = Options()
      prefs = {
        "translate_whitelists": {"da":"en"},
        "translate":{"enabled":"true"}
      }
      options.add_experimental_option("prefs", prefs)
      driver = webdriver.Chrome(ChromeDriverManager().install(),options=options)
      
      
      SHARES +/- + / -% MOST RECENT ÅTD% VOLUME TURNOVER MARKET VALUE
      Abn Amro Bank NV -0.32 -4.08% 7.48 -53.90% 7.9 million 59.0 million -
      Adyen 81.00 5.62% 1523.00 108% 954 082 1.5 billion -
      Aegon -0.08 -3.49% 2.16 -45.47% 17.4 million 37.5 million -
      Ahold Del 0.25 0.98% 25.65 19.74% 8.0 million 204.1 million -
      Akzo Nobel 0.14 0.16% 85.86 -3.16% 1.1 million 90.6 million -
      

      导入

      from selenium.webdriver.common.by import By
      from selenium.webdriver.support.ui import WebDriverWait 
      from selenium.webdriver.support import expected_conditions as EC
      

      【讨论】:

        【解决方案3】:

        获取表信息WebDriverWait() 和visibility_of_element_located() 并关注css selector

        driver.get("https://borsen.dk/investor/kurser/eur-aktier/?filter=aex25")
        WebDriverWait(driver,20).until(EC.visibility_of_element_located((By.CSS_SELECTOR,".compressed-table")))
        html_source =driver.page_source
        driver.quit()
        soup=BeautifulSoup(html_source, "html5lib")
        table=soup.select_one(".compressed-table")
        df = pd.read_html(str(table), flavor='html5lib', header=0, thousands='.', decimal=',')
        print(df[0])
        

        输出:

          Unnamed: 0               Aktie    +/-  ... Markedsværdi  Sektor    Tid
        0          NaN  Abn Amro Bank N.V.  -0.32  ...            -     NaN  16:39
        1          NaN               Adyen  81.00  ...            -     NaN  16:39
        2          NaN               Aegon  -0.08  ...            -     NaN  16:35
        3          NaN           Ahold Del   0.25  ...            -     NaN  16:35
        4          NaN          Akzo Nobel   0.14  ...            -     NaN  16:36
        5          NaN    Arcelormittal Sa   0.08  ...            -     NaN  16:39
        6          NaN   Asm International   0.35  ...            -     NaN  16:37
        7          NaN        Asml Holding   1.50  ...            -     NaN  16:35
        8          NaN       Asr Nederland  -0.22  ...            -     NaN  16:35
        9          NaN             Dsm Kon   2.25  ...            -     NaN  16:39
        10         NaN           Galapagos  -1.45  ...            -     NaN  16:35
        11         NaN            Heineken   0.74  ...            -     NaN  16:35
        12         NaN                Imcd   1.85  ...            -     NaN  16:35
        13         NaN      Ing Groep N.V.  -0.19  ...            -     NaN  16:38
        14         NaN   Just Eat Takeaway   0.08  ...            -     NaN  16:39
        15         NaN             Kpn Kon  -0.03  ...            -     NaN  16:35
        16         NaN            Nn Group  -0.35  ...            -     NaN  16:35
        17         NaN         Philips Kon  -0.08  ...            -     NaN  16:35
        18         NaN              Prosus  -1.52  ...            -     NaN  16:39
        19         NaN         Randstad Nv  -0.98  ...            -     NaN  16:35
        20         NaN                Relx   0.00  ...            -     NaN  16:36
        21         NaN  Royal Dutch Shella  -0.24  ...            -     NaN  16:37
        22         NaN  Unibail-Rodamco-We  -3.79  ...            -     NaN  16:37
        23         NaN            Unilever  -1.04  ...            -     NaN  16:38
        24         NaN      Wolters Kluwer  -0.04  ...            -     NaN  16:35
        
        [25 rows x 13 columns]
        

        你也可以使用find()

        driver.get("https://borsen.dk/investor/kurser/eur-aktier/?filter=aex25")
        WebDriverWait(driver,20).until(EC.visibility_of_element_located((By.CSS_SELECTOR,".compressed-table")))
        html_source =driver.page_source
        driver.quit()
        soup=BeautifulSoup(html_source, "html5lib")
        df=pd.read_html(str(soup.find('table',class_='heavy-table ncpulse-fav-table ncpulse-sortable compressed-table')))[0]
        print(df)
        

        【讨论】:

          【解决方案4】:

          要从表中提取内容,因为<table> 是基于Angular 的元素,使用Selenium 而不是presence_of_element_located(),您必须为visibility_of_element_located() 诱导WebDriverWait,您可以使用以下任一Locator Strategies:

          • 使用CSS_SELECTOR

            print(WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "table.heavy-table.ncpulse-fav-table.ncpulse-sortable.compressed-table"))).text)
            
          • 使用XPATH

            print(WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//table[@class='heavy-table ncpulse-fav-table ncpulse-sortable compressed-table']"))).text)
            
          • 注意:您必须添加以下导入:

            from selenium.webdriver.support.ui import WebDriverWait
            from selenium.webdriver.common.by import By
            from selenium.webdriver.support import expected_conditions as EC
            
          • 控制台输出:

            AKTIE +/- +/-% SENESTE ÅTD% BUD UDBUD VOLUMEN OMSÆTNING MARKEDSVÆRDI TID
            Abn Amro Bank N.V. -0,32 -4,08% 7,48 -53,90% - - 7,9 mio 59,0 mio - 21:09
            Adyen 81,00 5,62% 1523,00 108% - - 954 082 1,5 mia - 21:09
            Aegon -0,08 -3,49% 2,16 -45,47% - - 17,4 mio 37,5 mio - 21:05
            Ahold Del 0,25 0,98% 25,65 19,74% - - 8,0 mio 204,1 mio - 21:05
            Akzo Nobel 0,14 0,16% 85,86 -3,16% - - 1,1 mio 90,6 mio - 21:06
            Arcelormittal Sa 0,08 0,66% 11,53 -26,26% - - 11,9 mio 137,3 mio - 21:09
            Asm International 0,35 0,29% 119,10 21,23% - - 403 117 48,0 mio - 21:07
            Asml Holding 1,50 0,49% 308,45 17,56% - - 2,3 mio 712,7 mio - 21:05
            Asr Nederland -0,22 -0,73% 29,76 -4,97% - - 740 781 22,0 mio - 21:05
            Dsm Kon 2,25 1,66% 138,20 21,52% - - 680 867 94,1 mio - 21:09
            Galapagos -1,45 -1,22% 117,70 -36,89% - - 475 793 56,0 mio - 21:05
            Heineken 0,74 0,94% 79,10 -15,50% - - 1,1 mio 88,0 mio - 21:05
            Imcd 1,85 1,80% 104,85 36,23% - - 922 391 96,7 mio - 21:05
            Ing Groep N.V. -0,19 -2,80% 6,60 -38,24% - - 43,4 mio 286,2 mio - 21:08
            Just Eat Takeaway 0,08 0,09% 91,70 11,56% - - 1,1 mio 100,2 mio - 21:09
            Kpn Kon -0,03 -1,54% 2,11 -15,04% - - 21,4 mio 45,1 mio - 21:05
            Nn Group -0,35 -1,06% 32,80 3,82% - - 2,4 mio 79,6 mio - 21:05
            Philips Kon -0,08 -0,20% 39,42 -9,42% - - 5,2 mio 205,9 mio - 21:05
            Prosus -1,52 -1,89% 78,74 18,35% - - 15,0 mio 1,2 mia - 21:09
            Randstad Nv -0,98 -2,09% 45,93 -15,63% - - 698 496 32,1 mio - 21:05
            Relx 0,00 0,03% 19,64 -10,24% - - 1,9 mio 36,6 mio - 21:06
            Royal Dutch Shella -0,24 -2,07% 11,45 -54,58% - - 21,1 mio 241,2 mio - 21:07
            Unibail-Rodamco-We -3,79 -10,53% 32,20 -75,02% - - 6,6 mio 213,2 mio - 21:07
            Unilever -1,04 -2,00% 50,98 2,00% - - 8,2 mio 417,5 mio - 21:08
            Wolters Kluwer -0,04 -0,05% 72,88 14,19% - - 803 644 58,6 mio - 21:05
            

          【讨论】:

            猜你喜欢
            • 2022-11-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-07-22
            • 2019-03-25
            相关资源
            最近更新 更多