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

文章目录

  • 0 基础知识
    • table类型的表格网页结构
    • read_html()函数
  • 1 快速抓取法
    • 1.1 思路
    • 1.2 代码
  • 2 完整爬虫抓取法
    • 2.1 思路
    • 2.2 代码
  • 3 小结


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

网站中很多表格,我们想对这些表格进行整理汇总、或者是筛选,或者是处理分析

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

  • 如果需要抓的表格很少或只需要抓一次,那么推荐快速抓取法 [引文1]
  • 如果页数比较多,推荐完整爬虫抓取法 [引文2]。解析函数用了BeautifulSoup和css选择器,这种方法定位提取表格所在的id为#myTable04的table代码段,更为准确。

0 基础知识

table类型的表格网页结构

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

标签中,
类型的表格网页结构大致如下:

............ ... ............
...
...

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

	: 定义表格
	: 定义表格的页眉
	: 定义表格的主体
	: 定义表格的行
: 定义表格的表头 : 定义表格单元

使用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:查看网页元素。 在目标网页中,右键“审查元素”,发现是类型的网页结构,可以用read_html()抓取。
    【Python笔记】read_html():获取table类型网页表格数据_第1张图片
  • 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)
    

    【Python笔记】read_html():获取table类型网页表格数据_第2张图片

    2 完整爬虫抓取法

    2.1 思路

    这里以中商情报网为例,具体步骤如下:

    • step0:查看网页元素。 在目标网页中,右键“审查元素”,发现是

    类型的网页结构,可以用read_html()抓取。
    【Python笔记】read_html():获取table类型网页表格数据_第3张图片

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

    【Python笔记】read_html():获取table类型网页表格数据_第4张图片

    3 小结

    最后,需说明不是所有表格都可以用这种方法爬取

    比如这个网站中的表格,表面是看起来是表格,但在html中不是前面的table格式,而是list列表格式。这种表格则不适用read_html爬取。得用其他的方法,比如selenium
    【Python笔记】read_html():获取table类型网页表格数据_第5张图片

    引自:
    [1] 关于python获取网页表格数据(read_html()方法)
    [2] 利用pandas库中的read_html方法快速抓取网页中常见的表格型数据

    你可能感兴趣的:(Python笔记,python)