【Python笔记】read_html():获取table类型网页表格数据

  • Post author:
  • Post category:python



常见的各种官网都有这样一种情况:


网站中很多表格

,我们想对这些表格进行

整理汇总

、或者是

筛选

,或者是

处理分析


于是我们需要考虑:如何将网页表格数据使用python保存为Excel文件?

  • 如果需要抓的表格很少或只需要抓一次,那么推荐

    快速抓取法


    [引文1]

  • 如果页数比较多,推荐

    完整爬虫抓取法


    [引文2]

    。解析函数用了BeautifulSoup和css选择器,这种方法定位提取表格所在的id为#myTable04的table代码段,更为准确。



0 基础知识



table类型的表格网页结构

一般情况下,网页的表格数据主要是在

<table>

标签中,

<table>

类型的表格网页结构大致如下:

<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>

简单解释上文出现的几种标签含义:

<table>	: 定义表格
<thead>	: 定义表格的页眉
<tbody>	: 定义表格的主体
<tr>	: 定义表格的行
<th>	: 定义表格的表头
<td>	: 定义表格单元

使用pandas的

read_html()

方法就可以读取标签中的内容。



read_html()函数

pandas.read_html(io,
				 match='.+', 
				 flavor=None, 
				 header=None,
				 index_col=None,
				 skiprows=None, 
				 attrs=None,
				 parse_dates=False,
				 tupleize_cols=None,
				 thousands=', ', 
				 encoding=None, 
				 decimal='.',
				 converters=None,
				 na_values=None,
				 keep_default_na=True,
				 displayed_only=True)


常用的参数:

  • io:可以是url、html文本、本地文件等
  • flavor:解析器;
  • header:标题行;
  • skiprows:跳过的行;
  • attrs:属性,比如 attrs = {‘id’: ‘table’};
  • parse_dates:解析日期

注意:返回的结果是

DataFrame

组成的

list



1 快速抓取法



1.1 思路

这里以

NBA Player Salaries – 2020-2021

为例,具体步骤如下:


  • step0:查看网页元素。

    在目标网页中,右键“审查元素”,发现是

    <table>

    类型的网页结构,可以用

    read_html()

    抓取。

    在这里插入图片描述

  • step1:确定抓取数据量和网页类型。

    表数据共14页,数据量不大;且1-14页的网址只有page的变化,属于静态网页。

  • step2:代码思路。

    核心思路:使用pandas库中的

    read_html()

    函数,采用

    快速抓取法

    完成网页表格数据的收集。建立空白DataFrame结构 – 建立爬取网址合集urls – 依次爬取每一页的表格数据并append – 导出最终数据到csv。



1.2 代码

# 导入库
import pandas as pd

# 建立空白DataFrame
df=pd.DataFrame()

# 建立爬取网址合集urls
url_ori='http://www.espn.com/nba/salaries/_/page/'
urls=[url_ori+str(i) for i in range(1,15)]

# 依次爬取每一页的表格数据并append
for i,url in enumerate(urls):
    print(i+1)
    df=df.append(pd.read_html(url),ignore_index=True)
    
df.shape
    
# 数据筛选,ignore_index没有删除数据行中夹杂的标题行
df=df[df[0]!='RK'][[1,2,3]].reset_index(drop=True)

# 其他处理:
# df[1].apply(lambda x:x.split(',')[0])
# df[3].apply(lambda x:x[1:])

# 数据导出到CSV
df.to_csv(r'd:/desktop/NBA Player Salaries-2020-2021.csv',header=['NAME','TEAM','SALARY'],index=False)

在这里插入图片描述



2 完整爬虫抓取法



2.1 思路

这里以

中商情报网

为例,具体步骤如下:


  • step0:查看网页元素。

    在目标网页中,右键“审查元素”,发现是

    <table>

    类型的网页结构,可以用

    read_html()

    抓取。

    在这里插入图片描述


  • step1:确定抓取数据量和网页类型。

    表数据共208页,数据量较大;且1-208页的网址只有pageNum的变化,属于静态网页。


  • step2:代码思路。

    核心思路:使用pandas库中的

    read_html()

    函数,采用

    完整爬虫抓取法

    完成网页表格数据的收集。将整个爬取分为网页提取、内容解析、数据存储等步骤,依次建立相应的函数 – 主函数建立空白DataFrame结构 – 依次爬取每一页的表格数据并append – 导出最终数据到csv。



2.2 代码

import pandas as pd
import requests
from bs4 import BeautifulSoup
from lxml import etree
from urllib.parse import urlencode  # 编码 URL 字符串
import time

start_time = time.time()  #计算程序运行时间

# 网页提取
def get_one_page(i):
    try:
        headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36'}
        paras = {
                    'reportTime': '2017-12-31',#可以改报告日期,比如2018-6-30获得的就是该季度的信息
                    'pageNum': i   #页码
                }
        # https://s.askci.com/stock/a/?reportTime=2017-12-31&pageNum=1
        # urlencode(paras)的值为:reportTime=2017-12-31&pageNum=1
        url = 'http://s.askci.com/stock/a/?' + urlencode(paras)
        response = requests.get(url,headers = headers)
        if response.status_code == 200:
            return response.text
        return None
    except RequestException:
        print('爬取失败')
        
# 内容解析
def parse_one_page(html):
    soup = BeautifulSoup(html,'lxml')
    content = soup.select('#myTable04')[0] #[0]将返回的list改为bs4类型
    tbl = pd.read_html(content.prettify(),header = 0)[0]# prettify()优化代码,[0]从pd.read_html返回的list中提取出DataFrame
    tbl.rename(columns = {'序号':'serial_number',
                          '股票代码':'stock_code', 
                          '股票简称':'stock_abbre', 
                          '公司名称':'company_name', 
                          '省份':'province', 
                          '城市':'city', 
                          '主营业务收入(201712)':'main_bussiness_income', 
                          '净利润(201712)':'net_profit', 
                          '员工人数':'employees', 
                          '上市日期':'listing_date', 
                          '招股书':'zhaogushu', 
                          '公司财报':'financial_report', 
                          '行业分类':'industry_classification', 
                          '产品类型':'industry_type', 
                          '主营业务':'main_business'},inplace = True)
    return tbl
    # tbl = pd.DataFrame(tbl,dtype = 'object') #dtype可统一修改列格式为文本

# 数据存储
def write_to_csv(df):
    df.to_csv(r'd:\desktop\test.csv',index=False)

# 主函数
def main(page):
    df=pd.DataFrame()
    for i in range(1,page):  
        html = get_one_page(i)
        tbl = parse_one_page(html)
        df=df.append(tbl)
    write_to_csv(df)
        

# 单进程
if __name__=='__main__':
    # 爬取前n=3页的数据
    n=3
    main(n+1)
    endtime = time.time()-start_time
    print('程序爬了{}页的表格数据,运行了{:.2f}秒'.format(n,endtime))

在这里插入图片描述



3 小结

最后,需说明

不是所有表格都可以用这种方法爬取

比如这个网站中的表格,表面是看起来是表格,但在html中不是前面的

table

格式,而是

list

列表格式。这种表格则不适用

read_html

爬取。得用其他的方法,比如

selenium



在这里插入图片描述

引自:

[1]

关于python获取网页表格数据(read_html()方法)


[2]

利用pandas库中的read_html方法快速抓取网页中常见的表格型数据



版权声明:本文为qq_36056219原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。