【问题标题】:Screen Scrape Table, Clean Up, and Load to Data Frame屏幕抓取表、清理和加载到数据框
【发布时间】:2019-05-21 11:24:28
【问题描述】:

我尝试了几种循环遍历 TR 元素和 TE 元素的方法,并发现了如何遍历表中的这些行来导入我想要获取的数据。然后,我找到了一种更简单的方法来获取相同的数据,而无需使用循环。这是我的代码。

from bs4 import BeautifulSoup
import requests
import pandas as pd            
url = "https://markets.on.nytimes.com/research/markets/holidays/holidays.asp?display=market&exchange=SGO"
r = requests.get(url)
data = r.text
soup = BeautifulSoup(data, "lxml")
table = soup.find_all('table')[0]
print(table.prettify())

唯一的问题是数据带有所有的 HTML 格式,像这样。

<table id="holidayTable">
 <tr>
  <th class="left light" colspan="3">
   Holiday
  </th>
  <th class="left light">
   Markets Closed
  </th>
 </tr>
 <tr>
  <td class="bold left" valign="top">
   01/01/2018

如何清理这些数据并将其加载到数据框中?我希望它看起来基本上像这样。

感谢您抽出宝贵时间查看此内容!

【问题讨论】:

    标签: python python-3.x dataframe web-scraping beautifulsoup


    【解决方案1】:

    简单的方法是:

    import pandas as pd
    
    url = "https://markets.on.nytimes.com/research/markets/holidays/holidays.asp?display=market&exchange=SGO"
    
    dfs = pd.read_html(url)
    df = dfs[0]
    

    但这是练习 BeautifulSoup 的一个很好的例子,因为它的标签非常干净。您找到了 table 标记,现在您只需遍历行并将它们放入数据框中。

    首先我初始化一个空白数据框来存储我的结果:

    results = pd.DataFrame()

    然后我在你存储的表中找到所有tr标签:

    rows = table.find_all('tr')

    接下来对于每一行,我找到标记为td 的数据并放入一个列表中:

    data = row.find_all('td')
    row_data = [ x.text for x in data ]
    

    我将它放入一个临时数据框中,用于附加到我的初始结果数据框:

    temp_df = pd.DataFrame([row_data])
    results = results.append(temp_df)
    

    最后我删除空行并重置索引。我不知道您希望列是什么,但您可以重命名最后一行中的列。或者列标题通常是表格的th 标记,您可以随时返回并获取它们。

    完整代码:

    from bs4 import BeautifulSoup
    import requests
    import pandas as pd            
    url = "https://markets.on.nytimes.com/research/markets/holidays/holidays.asp?display=market&exchange=SGO"
    r = requests.get(url)
    data = r.text
    soup = BeautifulSoup(data, "lxml")
    table = soup.find_all('table')[0]
    
    
    results = pd.DataFrame()
    rows = table.find_all('tr')
    for row in rows:
        data = row.find_all('td')
        row_data = [ x.text for x in data ]
        temp_df = pd.DataFrame([row_data])
    
        results = results.append(temp_df)
    
    results = results.dropna(how='all').reset_index(drop = True)
    results.columns = ['col1', 'col2', 'col3', 'col4']
    

    【讨论】:

    • 哇!太棒了!因此,将表格转换为数据框的过程实际上会清理所有内容。很高兴知道!!感谢您对此的帮助!
    【解决方案2】:

    以略微不同的方式执行相同操作,您可以查看以下方法。在脚本中使用[1:] 踢出th 值。我试图摆脱冗余:

    from bs4 import BeautifulSoup
    import requests
    import pandas as pd 
    
    url = "https://markets.on.nytimes.com/research/markets/holidays/holidays.asp?display=market&exchange=SGO"
    
    res = requests.get(url)
    soup = BeautifulSoup(res.text, "lxml")
    data = pd.DataFrame()
    
    for rows in soup.find(id='holidayTable').find_all('tr')[1:]:
        tds = [row.text for row in rows.find_all('td')]
        add_list_to_df = pd.DataFrame([tds])
        data = data.append(add_list_to_df)
    
    df = pd.DataFrame({"Header1":data[0],"Header2":data[1],"Header3":data[2],"Header4":data[3]}).to_string(index=False)
    print(df)
    

    【讨论】:

    • 完美运行!谢谢!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多