首頁>技術>

Web爬取是從Web上收集和解析資料的過程。Python社群已經開發出一些非常強大的web爬取工具。其中,Pandas read_html()是從html表中爬取資料的一種快速方便的方法。

在本文中,你將學習Pandas read_html()來處理以下常見問題,並幫助你進行web爬取。

1.從字串讀取表

2.從URL讀取表

3.從檔案讀取表

4.使用parse_dates分析日期列

5.使用converters顯式轉換型別

6.多索引、標題和索引列

7.用match匹配表

8.使用屬性篩選表

9.使用缺失值

請檢查Notebook的原始碼(https://github.com/BindiChen/machine-learning/blob/master/data-analysis/024-pandas-read_html/pandas-read_html.ipynb)。

1.從字串中讀取表

在第一個示例中,我們將從字串中讀取HTML表。

html_string = """<table> <thead> <tr> <th>date</th> <th>name</th> <th>year</th> <th>cost</th> <th>region</th> </tr> </thead> <tbody> <tr> <td>2020-01-01</td> <td>Jenny</td> <td>1998</td> <td>0.2</td> <td>South</td> </tr> <tr> <td>2020-01-02</td> <td>Alice</td> <td>1992</td> <td>-1.34</td> <td>East</td> </tr> <tr> <td>2020-01-03</td> <td>Tomas</td> <td>1982</td> <td>1.00023</td> <td>South</td> </tr> </tbody></table>"""

要從字串中讀取表,請執行以下操作:

dfs = pd.read_html(html_string)

現在,我們得到的結果不是Pandas資料幀而是Python列表。如果使用type()函式,可以看到:

>>> type(dfs)list

如果要獲取表,可以使用索引訪問它:

dfs[0]

結果看起來很棒。讓我們看看dfs[0].info()的資料型別。預設情況下,數值列被轉換為數值型別,例如,year和cost列分別被轉換為int64和float64。

>>> df[0].info()RangeIndex: 3 entries, 0 to 2Data columns (total 5 columns): # Column Non-Null Count Dtype --- ------ -------------- -----  0 date 3 non-null object  1 name 3 non-null object  2 year 3 non-null int64  3 cost 3 non-null float64 4 region 3 non-null object dtypes: float64(1), int64(1), object(3)memory usage: 248.0+ bytes
2.從URL讀取表

Pandas read_html()接受URL。讓我們透過一個例子來看看這是如何工作的。

URL = 'https://en.wikipedia.org/wiki/London'dfs = pd.read_html(URL)

與從字串讀取相同,它返回一個數據幀列表。如果我們執行len(dfs),我們可以從給定的URL得到31個表。

>>> print(f'Total tables: {len(dfs)}')31

下面是dfs[6]的一個例子:

3.從檔案讀取表

Pandas read_html()接受一個檔案。讓我們透過一個例子來看看這是如何工作的。

file_path = 'html_string.txt'with open(file_path, 'r') as f: dfs = pd.read_html(f.read())dfs[0]

注意:以下教程將從字串中讀取資料,因為隨著時間的推移,網頁內容可能變更。

4.使用parse_dates分析日期列

日期列作為物件資料型別讀取。要正確讀取日期列,可以使用引數parse_dates指定日期列的列表。

>>> dfs = pd.read_html(html_string, parse_dates=['date'])>>> dfs[0].info()RangeIndex: 3 entries, 0 to 2Data columns (total 5 columns): # Column Non-Null Count Dtype --- ------ -------------- -----  0 date 3 non-null datetime64[ns] 1 name 3 non-null object  2 year 3 non-null int64  3 cost 3 non-null float64  4 region 3 non-null object dtypes: datetime64[ns](1), float64(1), int64(1), object(2)memory usage: 248.0+ bytes
5.使用converters顯式轉換型別

預設情況下,數值列被轉換為數值型別,例如,我們看到的year和cost列。但並非所有的數字文字資料都必須是數字型別,例如,所有值都以零開頭的ID列。

ID = 0001

此外,有時可能需要顯式地進行型別轉換以確保資料型別的完整性。對於這些要求,我們可以使用引數轉換器顯式地進行型別轉換:

dfs = pd.read_html(html_string, converters={ 'ID': str, 'year': int, 'cost': float,})
6.多索引、標題和索引列

預設情況下,位於<thead>中的<th>或<td>元素用於形成列索引,如果<thead>中包含多行,則建立一個多索引。

下面是一個在<thead>中包含多行的HTML表的示例。

html_string = """<table> <thead> <tr> <th colspan="5">Year 2020</th> </tr> <tr> <th>date</th> <th>name</th> <th>year</th> <th>cost</th> <th>region</th> </tr> </thead> <tbody> <tr> <td>2020-01-01</td> <td>Jenny</td> <td>1998</td> <td>1.2</td> <td>South</td> </tr> <tr> <td>2020-01-02</td> <td>Alice</td> <td>1992</td> <td>-1.34</td> <td>East</td> </tr> </tbody></table>"""

它建立多重索引,因為<thead>中有多行。

dfs = pd.read_html(html_string)dfs[0]

指定標題行:

dfs = pd.read_html(html_string, header=1)dfs[0]

指定索引列:

dfs = pd.read_html(html_string, header=1, index_col=0)dfs[0]
7.用match匹配表

引數匹配採用字串或正則表示式。該值預設為.+(匹配任何非空字串),並將返回所有表。

我們透過一個例子來看看這是如何工作的。

html_string = """<table id="report"> <caption>2020 report</caption> <thead> <tr> <th>date</th> <th>name</th> </tr> </thead> <tbody> <tr> <td>2020-01-01</td> <td>Jenny</td> </tr> <tr> <td>2020-01-02</td> <td>Alice</td> </tr> </tbody></table><table> <caption>Average income</caption> <thead> <tr> <th>name</th> <th>income</th> </tr> </thead> <tbody> <tr> <td>Tom</td> <td>200</td> </tr> <tr> <td>James</td> <td>300</td> </tr> </tbody></table>"""

要讀取包含特定文字的表:

# 標題中的文字dfs = pd.read_html(html_string, match='2020 report')# 表格單元格中的文字dfs = pd.read_html(html_string, match='James')
8.使用屬性篩選表

引數attrs接受任何有效的HTML標記屬性的字典來篩選表。例如:

dfs = pd.read_html(html_string, attrs={'id': 'report'})

id是有效的HTML標記屬性。

9.使用缺失值

預設情況下,所有空字串都被視為缺失值,並作為NaN讀取。

下面是一個HTML表格的示例,其中的< td >單元格中有一些空字串。

html_string = """<table> <tr> <th>date</th> <th>name</th> <th>year</th> <th>cost</th> <th>region</th> </tr> <tr> <td>2020-01-01</td> <td>Jenny</td> <td>1998</td> <td>1.2</td> <td>South</td> </tr> <tr> <td>2020-01-02</td> <td>Alice</td> <td>1992</td> <td></td> <td>East</td> </tr> <tr> <td>2020-01-03</td> <td>Tomas</td> <td>1982</td> <td></td> <td>South</td> </tr></table>"""

以預設設定讀取。

dfs = pd.read_html(html_string)dfs[0]

為了保留這些空字串,我們可以將引數keep_default_na設定為False。

dfs = pd.read_html(html_string, keep_default_na=False)

有時,對於缺少的值,你可能有其他字元表示法。如果我們知道什麼型別的字元用作表中的缺失值,我們可以使用na_values引數處理它們:

dfs = pd.read_html(html_string, na_values=['?', '&'])

當資料幀已經建立好後,我們可以使用pandas replace()函式來處理這些值:

df_clean = dfs[0].replace({ "?": np.nan, "&": np.nan })
結論

Pandas read_html()函式是一種快速方便地從html表中獲取資料的方法。

謝謝你的閱讀。請檢視Notebook的原始碼,如果你對機器學習的實際方面感興趣,請繼續關注:https://github.com/BindiChen/machine-learning/blob/master/data-analysis/024-pandas-read_html/pandas-read_html.ipynb。

30
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • Mysql六:SQL語句的最佳化