Pandas 爬蟲,一行代碼迅速爬網頁!

文 | 閒歡

來源:Python 教授「ID: justpython」

提到爬取網頁數據,大家最先想到的常規方式是通過 requests 請求網頁數據,然後使用 lxml 解析定位網頁節點,從而獲取所需數據。

但是對於一些簡單的網頁表格數據抓取來講,我們沒有必要去研究頁面的結構,然後解析頁面,甚至通過晦澀難懂的正則表達式去解析數據。

今天我就給大家介紹一個神器 —— 潘大師(Pandas),可以一行代碼即刻獲取網頁中的表格數據。

介紹

Pandas 自帶了一個 read_html() 的方法,通過這個方法可以直接獲取網頁中的所有表格數據。

當然,這個獲取方式也是有前提條件的,它要求網頁中的表格是我們常見的標準格式:

<table class="..." id="...">
    <thead>
    <tr>
    <th>...</th>
    </tr>
    </thead>
    <tbody>
        <tr>
            <td>...</td>
        </tr>
        <tr>...</tr>
        <tr>...</tr>
        <tr>...</tr>
        <tr>...</tr>
        ...
        <tr>...</tr>
        <tr>...</tr>
        <tr>...</tr>
        <tr>...</tr>        
    </tbody>
</table>

當你使用 F12 定位頁面表格時,如果出現的是這種標準的 HTML 表格,那麼我們就可以直接使用 read_html() 這個方法快速地獲取頁面的表格信息。

實例

下面我們以福布斯 500 強的新聞網頁(https://www.fortunechina.com/fortune500/c/2018-07/19/content_311046.htm)爲例,這個頁面整個是一個新聞網頁,在後面穿插一個福布斯排名的表格:

我們來看看這個簡潔而暴力的代碼實現:

data = pd.read_html('https://www.fortunechina.com/fortune500/c/2018-07/19/content_311046.htm',header=0,encoding='utf-8')
print(data)

打印出來的內容如下:

[      排名 上年排名                              公司名稱(中英文)  營業收入(百萬美元) 利潤(百萬美元)  國家
0      1    1                           沃爾瑪(WALMART)    500343.0     9862  美國
1      2    2                     國家電網公司(STATE GRID)    348903.1   9533.4  中國
2      3    3              中國石油化工集團公司(SINOPEC GROUP)    326953.0   1537.8  中國
3      4    4  中國石油天然氣集團公司(CHINA NATIONAL PETROLEUM)    326007.6   -690.5  中國
4      5    7          荷蘭皇家殼牌石油公司(ROYAL DUTCH SHELL)    311870.0    12977  荷蘭
..   ...  ...                                    ...         ...      ...  ..
495  496   --      河南能源化工集團(HENAN ENERGY & CHEMICAL)     23699.4    -68.6  中國
496  497  430   大同煤礦集團有限責任公司(DATONG COAL MINE GROUP)     23697.5     66.8  中國
497  498  452                   BAE系統公司(BAE SYSTEMS)     23591.6   1099.6  英國
498  499   --                    青島海爾(QINGDAO HAIER)     23563.2   1024.7  中國
499  500  419                        愛立信公司(ERICSSON)     23556.3  -4119.8  瑞典
[500 rows x 6 columns]]

驚不驚喜,意不意外?就是這麼簡單,接下來對這個表格數據需要怎麼處理直接從 data 裏面取就行。

細心的你可能發現這個輸出有個問題,好像外面包了一層中括號。

對,你沒看錯!其實我們的 data 是一個列表,這也就意味着如果網頁中有多個表格的話,我們也可以通過這一行代碼全部獲取。

我們再來看一個實例。

這次我選取的網頁是 https://www.boxofficemojo.com/ 。這個網頁有好幾個表格:

同樣地,我們來看我們的代碼:

data = pd.read_html('https://www.boxofficemojo.com/',header=0,encoding='utf-8')
print(data)

輸出是這樣子的:

[                      Eternals  $4,211,822
0     Clifford the Big Red Dog  $2,300,172
1                         Dune    $826,144
2               No Time to Die    $662,296
3  Venom: Let There Be Carnage    $375,377,                       Eternals  $6,243,758
0     Clifford the Big Red Dog  $3,280,603
1                         Dune  $1,225,876
2               No Time to Die    $993,982
3  Venom: Let There Be Carnage    $692,789,                       Eternals  $7,839,828
0     Clifford the Big Red Dog  $4,315,807
1                         Dune  $1,646,511
2               No Time to Die  $1,395,424
3  Venom: Let There Be Carnage  $1,042,997,                       Eternals $11,868,839
0     Clifford the Big Red Dog  $7,536,674
1                         Dune  $2,422,023
2               No Time to Die  $2,012,687
3  Venom: Let There Be Carnage  $1,847,858,                       Eternals  $7,141,461
0     Clifford the Big Red Dog  $4,775,010
1                         Dune  $1,474,474
2               No Time to Die  $1,125,239
3  Venom: Let There Be Carnage  $1,029,300,    1                     Eternals  $26.9M  false  false.1
0  2     Clifford the Big Red Dog  $16.6M   True    False
1  3                         Dune   $5.5M  False    False
2  4               No Time to Die   $4.5M  False    False
3  5  Venom: Let There Be Carnage   $3.9M  False    False,      Untitled Elvis Presley Project     Wide   Jun 3, 2022  →  Jun 24, 2022
0         Untitled Star Trek Sequel     Wide   Jun 9, 2023  →  Dec 22, 2023
1  Transformers: Rise of the Beasts     Wide  Jun 24, 2022  →   Jun 9, 2023
2                    The Contractor  Limited  Dec 10, 2021  →  Mar 18, 2022
3                National Champions     Wide           New  →  Dec 10, 2021,    1 Shang-Chi and the Legend of the Ten Rings  $224.4M  -
0  2               Venom: Let There Be Carnage  $202.6M  -
1  3                               Black Widow  $183.7M  -
2  4                         F9: The Fast Saga  $173.0M  -
3  5                     A Quiet Place Part II  $160.1M  -,    1 The Battle at Lake Changjin  $882.0M  -
0  2                     Hi, Mom  $822.0M  -
1  3           F9: The Fast Saga  $721.1M  -
2  4              No Time to Die  $708.4M  -
3  5       Detective Chinatown 3  $686.3M  -]

如果我們分別打印出這三個個表格:

data = pd.read_html('https://www.boxofficemojo.com/',header=0,encoding='utf-8')
print(data[0])
print(data[1])
print(data[2])

輸出就將這三個表格的數據分開了:

                      Eternals  $4,211,822
0     Clifford the Big Red Dog  $2,300,172
1                         Dune    $826,144
2               No Time to Die    $662,296
3  Venom: Let There Be Carnage    $375,377
                      Eternals  $6,243,758
0     Clifford the Big Red Dog  $3,280,603
1                         Dune  $1,225,876
2               No Time to Die    $993,982
3  Venom: Let There Be Carnage    $692,789
                      Eternals  $7,839,828
0     Clifford the Big Red Dog  $4,315,807
1                         Dune  $1,646,511
2               No Time to Die  $1,395,424
3  Venom: Let There Be Carnage  $1,042,997

上面就是 pandas 這個方法的簡單使用了。其實 read_html() 這個函數有很多參數可供調整,比如匹配方式、標題所在行、網頁屬性識別表格等等,具體說明可以參看 pandas 的官方文檔說明:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_html.html

總結

本文介紹的爬蟲方式很簡單,但是當你只想獲取一個網頁中的表格數據時,確實最有用最省時省力的方式。以後遇到這種需求,別再傻傻地去做解析了,直接一行代碼解決!

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/d3h7WUJnMgOsfO4TAKsxsw