【问题标题】:Trying to scrape table using Pandas from Selenium's result尝试从 Selenium 的结果中使用 Pandas 刮表
【发布时间】:2017-07-29 21:47:50
【问题描述】:

我正在尝试使用 Pandas 从 Javascript 网站上抓取表格。为此,我使用 Selenium 首先到达我想要的页面。我能够以文本格式打印表格(如注释脚本所示),但我也希望能够在 Pandas 中使用表格。我将我的脚本附在下面,希望有人能帮我解决这个问题。

import time
from selenium import webdriver
import pandas as pd

chrome_path = r"Path to chrome driver"
driver = webdriver.Chrome(chrome_path)
url = 'http://www.bursamalaysia.com/market/securities/equities/prices/#/?
filter=BS02'

page = driver.get(url)
time.sleep(2)


driver.find_element_by_xpath('//*[@id="bursa_boards"]/option[2]').click()


driver.find_element_by_xpath('//*[@id="bursa_sectors"]/option[11]').click()
time.sleep(2)

driver.find_element_by_xpath('//*[@id="bm_equity_price_search"]').click()
time.sleep(5)

target = driver.find_elements_by_id('bm_equities_prices_table')
##for data in target:
##    print (data.text)

for data in target:
    dfs = pd.read_html(target,match = '+')
for df in dfs:
    print (df)  

运行上面的脚本,我得到以下错误:

Traceback (most recent call last):
  File "E:\Coding\Python\BS_Bursa Properties\Selenium_Pandas_Bursa Properties.py", line 29, in <module>
    dfs = pd.read_html(target,match = '+')
  File "C:\Users\lnv\AppData\Local\Programs\Python\Python36-32\lib\site-packages\pandas\io\html.py", line 906, in read_html
    keep_default_na=keep_default_na)
  File "C:\Users\lnv\AppData\Local\Programs\Python\Python36-32\lib\site-packages\pandas\io\html.py", line 728, in _parse
    compiled_match = re.compile(match)  # you can pass a compiled regex here
  File "C:\Users\lnv\AppData\Local\Programs\Python\Python36-32\lib\re.py", line 233, in compile
    return _compile(pattern, flags)
  File "C:\Users\lnv\AppData\Local\Programs\Python\Python36-32\lib\re.py", line 301, in _compile
    p = sre_compile.compile(pattern, flags)
  File "C:\Users\lnv\AppData\Local\Programs\Python\Python36-32\lib\sre_compile.py", line 562, in compile
    p = sre_parse.parse(p, flags)
  File "C:\Users\lnv\AppData\Local\Programs\Python\Python36-32\lib\sre_parse.py", line 855, in parse
    p = _parse_sub(source, pattern, flags & SRE_FLAG_VERBOSE, 0)
  File "C:\Users\lnv\AppData\Local\Programs\Python\Python36-32\lib\sre_parse.py", line 416, in _parse_sub
    not nested and not items))
  File "C:\Users\lnv\AppData\Local\Programs\Python\Python36-32\lib\sre_parse.py", line 616, in _parse
    source.tell() - here + len(this))
sre_constants.error: nothing to repeat at position 0

我也尝试在 url 上使用 pd.read_html,但它返回了“未找到表”的错误。网址是:http://www.bursamalaysia.com/market/securities/equities/prices/#/?filter=BS08&board=MAIN-MKT&sector=PROPERTIES&page=1

【问题讨论】:

    标签: javascript python selenium


    【解决方案1】:

    您可以使用以下代码获取表格

    import time
    from selenium import webdriver
    import pandas as pd
    
    chrome_path = r"Path to chrome driver"
    driver = webdriver.Chrome(chrome_path)
    url = 'http://www.bursamalaysia.com/market/securities/equities/prices/#/?filter=BS02'
    
    page = driver.get(url)
    time.sleep(2)
    
    df = pd.read_html(driver.page_source)[0]
    print(df.head())
    

    这是输出

    No  Code    Name    Rem Last Done   LACP    Chg % Chg   Vol ('00)   Buy Vol ('00)   Buy Sell    Sell Vol ('00)  High    Low
    0   1   5284CB  LCTITAN-CB  s   0.025   0.020   0.005   +25.00  406550  19878   0.020   0.025   106630  0.025   0.015
    1   2   1201    SUMATEC [S] s   0.050   0.050   -   -   389354  43815   0.050   0.055   187301  0.055   0.050
    2   3   5284    LCTITAN [S] s   4.470   4.700   -0.230  -4.89   367335  430 4.470   4.480   34  4.780   4.140
    3   4   0176    KRONO [S]   -   0.875   0.805   0.070   +8.70   300473  3770    0.870   0.875   797 0.900   0.775
    4   5   5284CE  LCTITAN-CE  s   0.130   0.135   -0.005  -3.70   292379  7214    0.125   0.130   50  0.155   0.100
    

    要从所有页面获取数据,您可以抓取剩余页面并使用df.append

    【讨论】:

    • 非常感谢您指出解决方案。你的建议很有效!你介意解释一下 [0] 在 read_html 中的用途吗?我尝试在 read_html 文档中搜索它,但找不到任何解释。
    • 因为返回了两个表,而你想要的是第一个表。您可以通过df[0]df[1] 看到两个不同的表
    • @EricChoi 我建议你阅读pd.read_html(),它返回一个数据帧列表。
    【解决方案2】:

    答案:

    df = pd.read_html(target[0].get_attribute('outerHTML'))
    

    结果:

    target[0] 的原因:

    driver.find_elements_by_id('bm_equities_prices_table') 返回 selenium webelements 列表,在您的情况下,只有 1 个元素,因此 [0]

    get_attribute('outerHTML')的原因:

    我们想要获取元素的“html”。这种get_attribute methods有两种类型:'innerHTML' vs 'outerHTML'。我们选择了'outerHTML',因为我们需要包含当前元素,我想,表头所在的位置,而不是元素的内部内容。

    df[0]的原因

    pd.read_html() 返回一个数据帧列表,其中第一个是我们想要的结果,因此是[0]

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-12
      • 1970-01-01
      • 2019-12-15
      • 1970-01-01
      • 2019-08-12
      相关资源
      最近更新 更多