You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Selenium Python的find_element删除爬取表格中的空白值

Selenium爬取CME GROUP网站MONTH列空白值问题解决方案

问题说明

爬取CME GROUP目标页面时,获取到的元素列表中MONTH列(对应代码里的Date字段)有一半是空白值,但Price、Updated等其他列均能正常获取无空值。目标页面为:https://www.cmegroup.com/markets/energy/refined-products/gasoil-01-rotterdam-barges-swap.quotes.html

原爬取代码

main = driver.find_element(By.ID, "main-content")
time.sleep(10)
matches = main.find_elements(By.XPATH,
                          '//*[@id="productTabData"]/div/div/div/div/div/div[2]/div/div/div/div/div/div[5]/div/div/div/div[1]/div/table/tbody/tr')
time.sleep(10)
dane = []
for match in matches:
    Date = match.find_element(By.XPATH, "./td[1]/div/span/b").text
    Price = match.find_element(By.XPATH, "./td[5]").text
    Updated = match.find_element(By.XPATH, "./td[10]").text
    print(Date)
    table = {
        "DataPL" : Date,
        "GO" : Price,
        "Updated" : Updated
    }

    dane.append(table)
df=pd.DataFrame(dane)

临时解决方案(Pandas Shift)

目前通过Pandas的.shift()方法临时处理,但希望找到更优方案,临时代码如下:

df["DataPL"] = df["DataPL"].shift(-18)
df = df.iloc[0:17,:2]

更优解决方案

问题根源是目标表格的MONTH列采用了合并单元格布局:只有每组数据的第一行包含实际月份文本,后续行的该单元格为空。以下是两种更合理的处理方式:

方式1:复用最近有效月份值

遍历表格行时,若当前行的MONTH元素无文本,则复用最近一次获取到的有效月份值:

main = driver.find_element(By.ID, "main-content")
time.sleep(10)
matches = main.find_elements(By.XPATH,
                          '//*[@id="productTabData"]/div/div/div/div/div/div[2]/div/div/div/div/div/div[5]/div/div/div/div[1]/div/table/tbody/tr')
time.sleep(10)
dane = []
current_month = ""  # 存储最近一次有效的月份值

for match in matches:
    date_elem = match.find_element(By.XPATH, "./td[1]/div/span/b")
    date_text = date_elem.text.strip()
    
    # 更新或复用月份值
    if date_text:
        current_month = date_text
    Date = current_month
    
    Price = match.find_element(By.XPATH, "./td[5]").text.strip()
    Updated = match.find_element(By.XPATH, "./td[10]").text.strip()
    
    table = {
        "DataPL": Date,
        "GO": Price,
        "Updated": Updated
    }
    dane.append(table)

df = pd.DataFrame(dane)

方式2:按分组定位数据行

直接定位所有包含MONTH文本的行,再获取该组下的所有关联数据行:

main = driver.find_element(By.ID, "main-content")
time.sleep(10)
# 定位所有带有月份文本的行(合并单元格的首行)
month_rows = main.find_elements(By.XPATH,
                          '//*[@id="productTabData"]/div/div/div/div/div/div[2]/div/div/div/div/div/div[5]/div/div/div/div[1]/div/table/tbody/tr[./td[1]/div/span/b]')
time.sleep(10)
dane = []

for month_row in month_rows:
    current_month = month_row.find_element(By.XPATH, "./td[1]/div/span/b").text.strip()
    
    # 处理当前月份行本身的数据
    price = month_row.find_element(By.XPATH, "./td[5]").text.strip()
    updated = month_row.find_element(By.XPATH, "./td[10]").text.strip()
    dane.append({
        "DataPL": current_month,
        "GO": price,
        "Updated": updated
    })
    
    # 获取当前月份行之后的同组数据行(无月份文本的行)
    sibling_rows = month_row.find_elements(By.XPATH, "./following-sibling::tr[not(./td[1]/div/span/b)]")
    for row in sibling_rows:
        # 检查是否已经到下一个有月份的行,是的话停止遍历
        next_month_row = row.find_elements(By.XPATH, "./following-sibling::tr[./td[1]/div/span/b]")
        if next_month_row:
            break
        price = row.find_element(By.XPATH, "./td[5]").text.strip()
        updated = row.find_element(By.XPATH, "./td[10]").text.strip()
        dane.append({
            "DataPL": current_month,
            "GO": price,
            "Updated": updated
        })

df = pd.DataFrame(dane)

内容的提问来源于stack exchange,提问作者Adii

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 20:57:29