整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

Excel转html,浏览器在线预览excel

件转换工具新增exel转html功能,可在线预览excel。

excel转html

1.打开工具,选择excel文件

单sheet模式

2.转换文件

单sheet模式

可以看到提供了页数属性单sheet和多sheet,默认为单sheet,该种模式下,转换器会将excel里每个sheet页转换到一个html文件上,从上至下拼接起来,如下图:

单sheet模式转换文件

单sheet模式输出文件

多sheet模式

该模式下转换器会自动识别excel每个sheet页,并将每个sheet输出到html上对应tab页上,可以点击html上不同tab页切换查看内容,如下图。

多sheet模式输出文件

多sheet模式输出文件

工作生活中,经常会遇到excel文件需要在内部系统线上或线下发给其他人预览,但是又不想其他人有编辑权限,我们一般会将excel文件转图片或转pdf上传系统,这里提供了一种新途径直接转html,浏览器可在线预览,相关软件工作人员也可开发相应的excel在线预览功能。

exceljs是一个读取,操作和编写电子表格数据和样式到XLSX和JSON,从Excel电子表格文件逆向工程设计的项目。之所以称它最强,是因为它的功能强大,简直就是专门为Excel打造的前端处理插件,到目前为止,笔者还尚未见过比这个更强大的前端插件,由于其强悍的前端处理能力,这就意味着有很多操作将减轻服务器端压力,而且性能更加出色!







Github地址

https://github.com/exceljs/exceljs

安装

安装我们当然是首选npm

npm install exceljs

创建工作簿

var workbook = new Excel.Workbook();

设置工作簿属性

workbook.creator = 'Me';
workbook.lastModifiedBy = 'Her';
workbook.created = new Date(1985, 8, 30);
workbook.modified = new Date();
workbook.lastPrinted = new Date(2016, 9, 27);
// 将工作簿日期设置为1904日期系统
workbook.properties.date1904 = true;

工作簿视图

“工作簿”视图控制Excel在查看工作簿时打开多少个单独的窗口。

workbook.views = [
  {
    x: 0, y: 0, width: 10000, height: 20000,
    firstSheet: 0, activeTab: 1, visibility: 'visible'
  }
]

添加工作表

var sheet = workbook.addWorksheet('My Sheet');

用addWorksheet函数的第二个参数设置工作表的选项。

  • 例如:
// 创建一个红色标签颜色的工作表
var sheet = workbook.addWorksheet('My Sheet', {properties:{tabColor:{argb:'FFC0000'}}});

// 创建一个隐藏网格线的工作表
var sheet = workbook.addWorksheet('My Sheet', {properties: {showGridLines: false}});

// 创建一个第一行和列冻结的工作表
var sheet = workbook.addWorksheet('My Sheet', {views:[{xSplit: 1, ySplit:1}]});

删除工作表

使用工作表id从工作簿中删除工作表。

  • 例如:
// 创建工作表
var sheet = workbook.addWorksheet('My Sheet');

// 使用工作表ID删除工作表
workbook.removeWorksheet(sheet.id)

访问工作表

// 迭代所有sheet
// 注意:workbook.worksheets.forEach仍然可以工作,但这个方式更好
workbook.eachSheet(function(worksheet, sheetId) {
  // ...
});

// 按名称获取表格
var worksheet = workbook.getWorksheet('My Sheet');

// 按ID获取表格
var worksheet = workbook.getWorksheet(1);

。。。。。。以上只是部分文档中的介绍,感兴趣的小伙伴可以移步Github直接查看详细的文档,完整功能了解可参考下一个标题

PS:提供了中文文档

完整功能列表

  • 创建工作簿
  • 设置工作簿属性
  • 工作簿视图
  • 添加工作表
  • 删除工作表
  • 访问工作表
  • 工作表状态
  • 工作表属性
  • 页面设置
  • 页眉和页脚
  • 工作表视图
    1. 冻结视图
    2. 拆分视图
  • Auto Filters
  • 处理单个单元格
  • 合并单元格
  • 定义名称
  • 数据验证
  • 样式
    1. 数字格式
    2. 字体
    3. 对准
    4. 边框
    5. 填充
    6. 富文本
  • 大纲级别
  • 图片
  • 文件 I/O
  • XLSX:读 XLSX写 XLSX
  • CSV:读 CSV写 CSV
  • Streaming I/O:Streaming XLSX
  • 浏览器
  • 价类型
    1. 空值
    2. 合并单元格
    3. 数值
    4. 字符串值
    5. 日期值
    6. 超链接值
    7. 公式值
    8. 丰富的文本值
    9. 布尔值
    10. 错误值

    虽然以上功能还不能包括了Excel的所有功能,但也已经相当的丰富了!

    总结

    在之前的文章中曾介绍过另一个不错的前端Excel插件,感兴趣的可以去看一看,exceljs拥有这么丰富的功能,如果你想开发一个功能强大的Web电子表格,不妨多尝试尝试!

    读:本文要介绍的这些技法,会用Python读入各种格式的数据,并存入关系数据库或NoSQL数据库。

    作者:托马兹·卓巴斯(Tomasz Drabas)

    本文摘编自《数据分析实战》,如需转载请联系我们

    本文的源代码与数据集都可在Github上获取。如果要复制代码库,打开你的终端(Windows环境下的命令行、Cygwin或Git Bash,Linux/Mac环境下的Terminal),键入下面这条命令:

    git clone https://github.com/drabastomek/practicalDataAnalysisCookbook.git

    注意,你的机器得装好Git了。安装指南参见:

    • https://git-scm.com/book/en/v2/Getting-Started-Installing-Git

    我们将使用一个数据集,包含985项真实的房产交易。这些交易是连续5天内在Sacramento发生的。数据下载自:

    • https://support.spatialkey.com/spatialkey-sample-csv-data/

    精确地说,来自:

    • http://samplecsvs.s3.amazonaws.com/Sacramentorealestatetransactions.csv

    数据已转成多种格式,放在GitHub代码库的Data/Chapter01文件夹中。

    另外,你会学到如何从HTML文件中检索信息。出于这个目的,我们将使用Wikipedia上字母A打头的机场列表:

    • https://en.wikipedia.org/wiki/List_of_airports_by_IATA_code:_A

    我们将使用OpenRefine清理我们的数据集;它很擅长数据的读取、清理以及转换数据。

    01 用Python读写CSV/TSV文件

    CSV和TSV是两种特定的文本格式:前者使用逗号分隔数据,后者使用\t符。这赋予它们可移植性,易于在不同平台上共享数据。

    1. 准备

    要实践这个技法,你要先装好pandas模块。这些模块在Anaconda发行版Python中都有。如果你装的是这个版本,就省事了。如果不是,那你得安装pandas并确保正确加载。

    可以从

    • http://docs.continuum.io/anaconda/install

    下载Anaconda。

    如果你装了Python,没有pandas,你可以从

    • https://github.com/pydata/pandas/releases/tag/v0.17.1

    下载,并按照文档安装到你的操作系统中。

    • http://pandas.pydata.org/pandas-docs/stable/install.html

    此外没有要求了。

    2. 怎么做

    pandas模块提供了高性能的高级数据结构(比如DataFrame)以及一些基本的分析工具。

    DataFrame是一种数据结构,有点像Excel表格,列代表数据集的维度(例如,人的身高和体重),行存储着数据(例如,1000个人的具体身高和体重数据)。参考:

    • http://pandas.pydata.org/pandas-docs/stable/dsintro.html#dataframe

    这个模块提供了一些方法,便于读取各种格式的数据。下面这小块代码读取了CSV和TSV格式的数据,存入pandas DataFrame数据结构,然后写回到磁盘上(read_csv.py文件):

    import pandas as pd

    # 读出数据的文件名

    r_filenameCSV = '../../Data/Chapter01/realEstate_trans.csv'

    r_filenameTSV = '../../Data/Chapter01/realEstate_trans.tsv'

    # 写进数据的文件名

    w_filenameCSV = '../../Data/Chapter01/realEstate_trans.csv'

    w_filenameTSV = '../../Data/Chapter01/realEstate_trans.tsv'

    # 读取数据

    csv_read = pd.read_csv(r_filenameCSV)

    tsv_read = pd.read_csv(r_filenameTSV, sep='\t')

    # 输出头10行记录

    print(csv_read.head(10))

    print(tsv_read.head(10))

    # 写入文件

    with open (w_filenameCSV, 'w') as write_csv:

    write_csv.write(tsv_read.to_csv(sep=',', index=False))

    with open(w_filenameTSV, 'w') as write_tsv:

    write_tsv.write(csv_read.to_csv(sep='\t', index=False))

    打开命令行控制台(Windows环境下可使用命令或Cygwin,Linux/Mac环境下可使用Terminal),执行这条命令:

    python read_csv.py

    你会看到类似这样的输出:

    | Baths | beds | | city | latitude | longitude | price |

    | 0 | 1 | 2 | SACRAMENTO | 38.631913 | -121.434879 | 59222 |

    | 1 | 1 | 3 | SACRAMENTO | 38.478902 | -121.431028 | 68212 |

    | 2 | 1 | 2 | SACRAMENTO | 38.618305 | -121.443839 | 68880 |

    3. 原理

    首先加载pandas,以使用DataFrame及相关方法来读写数据。注意,关键词as赋给pandas一个别名pd。这样在后面的代码中,使用DataFrame或read_csv(...)方法时,我们就不用写出包的全名了。我们将(用于读和写的)文件名分别存于变量r_filenameCSV(TSV)和w_filenameCSV(TSV)。

    使用pandas的read_csv(...)方法读取数据。这个方法用途很广,接受一系列输入参数。但有一个参数是必需的,一个文件名或缓冲区,也就是一个打开的文件对象。要解析realEstate_trans.tsv文件,你要指定sep=‘\t’参数;默认情况下,read_csv(...)方法会推断文件使用的分隔符,不过我可不喜欢碰运气式编程,向来是指定分隔符的。

    两个文件中的数据一模一样,所以你可以输出一些记录,看看文件是否正确读入。这可通过对DataFrame对象应用.head(<no_of_rows>)方法达成,其中<no_of_rows>指的是要输出的行数。

    将数据存于pandas DataFrame对象意味着,数据的原始格式并不重要;一旦读入,它就能保存成pandas支持的任何格式。在前面这个例子中,我们就将CSV文件中读取的内容写入了TSV文件。

    无论读写,打开文件都要使用with open(…) as …:这个固定搭配。这种方式的优点在于,一旦完成了读写任务,即使由于某些原因抛出了异常,文件依然会正确关闭。

    异常是指程序员写代码时期望之外的情况。

    例如,假设你有一个文件,每行只包含一个数字:你打开这个文件,开始读取。每一行作为文本读入,你需要将文本转为一个整数——计算机可以将其作为数字理解(并处理)的数据结构,而非文本。

    当数据中只有数字时一切安好。然而,你将会认识到,我们收集的数据在某些方面是有瑕疵的,那么,某些行包含一个字母而非数字时,文本到整数的转换会失败,而Python会抛出一个异常。

    open(<filename>, ‘w’)会以写模式(w参数)打开<filename>指定的文件。也可以传入’r’指定以读模式打开文件。以’r+’模式打开文件允许数据的双向流动(读取和写入),这样你就可以在需要时往文件的末尾附加内容。你也可以指定rb或wb来处理二进制数据(而非文本)。

    to_csv(…)方法将DataFrame的内容转换为可存储于文本文件的格式。你要指定分隔符,比如sep=‘,’,以及是否保存DataFrame的索引,默认是保存的。我们不希望存,所以要指定index=False。

    用索引可以很方便地辨认、校准、访问DataFrame中的数据。索引可以是一列连续的数字(就像Excel中的行号)或日期;你还可以设定多列索引。索引列并不是数据(即便打印DataFrame对象时你会在屏幕上看到索引)。

    要了解更多关于索引的内容,可访问:

    • http://pandas.pydata.org/pandas-docs/stable/indexing.html

    4. 更多

    这里介绍读写CSV、TSV文件最方便最快捷的方法。如果你不想把数据存于pandas的DataFrame数据结构,你可以使用csv模块。像下面这样读取文件(read_csv_alternative.py文件):

    import csv

    # 读入数据的文件名

    r_filenameCSV = '../../Data/Chapter01/realEstate_trans.csv'

    r_filenameTSV = '../../Data/Chapter01/realEstate_trans.tsv'

    # 保存数据的数据结构

    csv_labels = []

    tsv_labels = []

    csv_data = []

    tsv_data = []

    # 读取数据

    with open(r_filenameCSV, 'r') as csv_in:

    csv_reader = csv.reader(csv_in)

    # 读取第一行,这是列标签

    csv_labels = csv_reader.__next__()

    # 遍历记录

    for record in csv_reader:

    csv_data.append(record)

    with open(r_filenameTSV, 'r') as tsv_in:

    tsv_reader = cvs.reader(tsv_in, delimiter='\t')

    tsv_labels = tsv_reader.__next__()

    for record in tsv_reader:

    tsv_data.append(record)

    # 打印标签

    print(csv_labels, '\n')

    print(tsv_labels, '\n')

    # 打印头10行记录

    print(csv_data[0:10], '\n')

    print(tsv_data[0:10], '\n')

    我们将标签和数据分别存储于csv(tsv)_labels和csv(tsv)_data两个列表。.reader(…)方法从文件中逐行读取数据。要创建.reader(…)对象,你要传入一个打开的CSV或TSV文件对象。另外,要读入TSV文件,你也得像DataFrame中一样指定分隔符。

    csv模块也提供了csv.writer对象,可将数据以CSV/TSV格式存储。参见csv模块的文档:

    • https://docs.python.org/3/library/csv.html

    5. 参考

    查阅pandas文档中讲解reader_csv(…)和write_csv(…)的部分,了解更多可传入的参数。文档位于:

    • http://pandas.pydata.org/pandas-docs/stable/io.html#io-read-csv-table

    02 用Python读写JSON文件

    JSON的全称是JavaScript Object Notation。这是个嵌套的、类似字典的结构,以逗号为分隔符,存储键值对;键与值之间以冒号分隔。JSON格式独立于具体平台(就像XML,我们将在 用Python读写XML文件介绍),便于平台之间共享数据。

    要深入了解JSON,可参考:

    • http://www.w3schools.com/json/

    1. 准备

    要实践这个技法,你要先装好pandas模块。此外没有要求了。

    2. 怎么做

    下面是读取JSON文件的代码。注意,我们假设已经引入了pandas模块,并以别名pd指代(read_json.py文件):

    # 读出数据的JSON文件

    r_filenameJSON = '../../Data/Chapter01/realEstate_trans.json'

    # 读取数据

    json_read = pd.read_json(r_filenameJSON)

    # 打印头10行记录

    print(json_read.head(10))

    3. 原理

    这段代码与前一节的类似。首先,指定JSON文件的名字——我们将其存于r_filenameJSON字符串中。然后,使用pandas的read_json(…)方法,传入r_filenameJSON。

    读出的数据存储于json_read这一DataFrame对象。进而使用.tail(…)方法打印出最后10条数据。要写入一个JSON文件,你可以对DataFrame使用.to_json()方法,将返回的数据写进一个文件,类似用Python读写CSV/TSV文件中介绍的流程。

    4. 更多

    也可以使用json模块来读写JSON文件。可以使用下面的代码从JSON文件中读取数据(read_json_alternative.py文件):

    # 读取数据

    with open('../../Data/Chapter01/realEstate_trans.json', 'r') as json_file:

    jsonread = json.loads(json_file.read())

    这段代码将realEstate_trans.json文件中读出的数据存入json_read列表。这里对文件使用了.read()方法,将文件内容全部读入内存。下面的代码将数据存储于一个JSON文件:

    # 写回到文件中

    with open('../../Data/Chapter01/realEstate_trans.json', 'w') as json_file:

    json_file.write(json.dumps(json_read))

    5. 参考

    参阅pandas文档中read_json的部分。文档位于:

    • http://pandas.pydata.org/pandas-docs/stable/io.html#io-json-reader

    03 用Python读写Excel文件

    以表格形式操作数据的文件格式中,Microsoft的Excel文件可以说是最流行的了。拿最新的XLSX格式来说,Excel可以在单个工作表中存储一百多万行及一万六千多列。

    1. 准备

    要实践这个技法,你要先装好pandas模块。此外没有要求了。

    2. 怎么做

    下面是读取JSON文件的代码。注意,我们假设已经引入pandas模块,并以pd指代(read_xlsx.py文件):

    # 读写数据的文件名

    r_filenameXLSX = '../../Data/Chapter01/realEstate_trans.xlsx'

    w_filenameXLSX = '../../Data/Chapter01/realEstate_trans.xlsx'

    # 打开Excel文件

    xlsx_file = pd.ExcelFile(r_filenameXLSX)

    # 读取内容

    xlsx_read = {

    sheetName: xlsx_file.parse(sheetName) for sheetName in xlsx_file.sheet_names

    }

    # 打印Sacramento头10份价格

    print (xlsx_read['Sacramento'].head(10)['price'])

    # 写入Excel文件

    xlsx_read['Sacramento'].to_excel (w_filenameXLSX, 'Sacramento', index=False)

    3. 原理

    类似之前的例子。用pandas的ExcelFile(...)方法打开XLSX文件,并赋给xlsx_file对象。用.parse(...)方法读取指定工作表的内容,并存储于xlsx_read字典。注意,通过ExcelFile对象的.sheet_names属性,你可以访问Excel文件中的所有工作表。

    创建xlsx_read字典时,我们使用了字典表达式,这个做法很Python:不是显式地遍历工作表,将元素添加到字典,而是使用字典表达式,让代码更可读、更紧凑。

    表达式效仿数学上的表示方法,这让代码更容易理解。比方说,2的幂次的列表:(A = (2^0, 2^1, 2^2, …, 2^8) = (2^x: 0 <= x < 9), x取整数)。使用表达式很容易转成Python代码:A = [2**x for x in range(0, 9)]。就创建了这样的列表:A = [1, 2, 4, 8, 16, 32, 64, 128, 256]。

    另外,Python里,表达式也比显式的循环要快那么一点点。

    • http://stackoverflow.com/questions/22108488/are-list-comprehensions-and-functional-functions-faster-than-for-loops

    range(<from>, <to>)函数生成了从<from>到<to>-1的一列整数。例如,range(0, 3)生成的序列是0,1,2.

    存储数据到Excel文件中也很简单。仅需调用.to_excel(...)方法,第一个参数传你要保存数据的文件名,第二个参数传工作表的名字。在我们的例子中,我们还指定了index=False,这样不会保存索引;默认情况下,.to_excel(...)方法保存A列的索引。

    4. 更多

    读取Excel文件,除了用pandas的read_excel(...)方法,你也可以选择其它Python模块。pandas使用xlrd读取数据并转成DataFrame。

    • https://secure.simplistix.co.uk/svn/xlrd/trunk/xlrd/doc/xlrd.html?p=4966

    对于XLSX文件,你也可以使用openpyxl模块(read_xlsx_alternative.py文件):

    import openpyxl as oxl

    # 读出数据的文件名

    r_filenameXLSX = '../../Data?Chapter01/realEstate_trans.xlsx'

    # 打开Excel文件

    xlsx_wb = oxl.load_workbook(filename=r_filenameXLSX)

    # 工作簿中所有工作表的名字

    sheets = xlsx_wb.get_sheet_names()

    # 提取'Sacramento'工作表

    xlsx_ws = xlsx_wb[sheets[0]]

    首先,读取Excel文件,存入xlsx_wb(工作簿)。从工作簿中提取所有工作表的名字,并存入sheets变量。这里我们的工作簿中只有一个工作表,所以sheets变量就等于'Sacramento'。我们用它创建一个xlsx_ws对象,以遍历所有的行:

    labels = [cell.value for cell in xlsx_ws.rows[0]]

    data = [] # 保存数据的列表

    for row in xlsx_ws.rows[1:]:

    data.append([cell.value for cell row])

    第一行是所有列的标签,最好还是单独存储——我们放到labels变量中。进而使用.rows迭代器,遍历工作表中每一行,将所有单元格中的数据加入data列表:

    print (

    [item[labels.index('price')] for item in data[0:10]]

    )

    代码最后打印出头10行的房屋价格。我们使用表达式生成价格的列表。如代码所示,对于列表对象,你可以调用.index(...)方法查找某一元素首次出现的位置。

    5. 参考

    • 查阅pandas文档中read_excel的部分。文档在

    http://pandas.pydata.org/pandas-docs/stable/io.html#io-excel

    另外,你可以访问

    • http://www.python-excel.org

    找到一系列模块,可帮你处理.xls和.xlsx等Excel文件格式。

    04 用Python读写XML文件

    XML的全称是eXtensible Markup Language(扩展标记语言)。尽管不像前面介绍的格式那样流行,不少网络API还是支持XML编码的。

    XML文档结构类似一棵树。读取内容时,我们首先访问根节点(通常来说,这个节点后面会跟着XML的声明<?xml version="1.0" encoding="UTF-8"?>;每个XML文档都要以这样的声明开头)。在我们的例子中,根节点是<records>。一个<record>...</record>中包含了一系列<var var_name=...>...</var>。

    当心:xml模块不安全。处理未知来源的XML消息时必须得小心。攻击者可能访问本地文件,发动DoS攻击等等。

    xml模块的文档参见:

    • https://docs.python.org/3/library/xml.html

    1. 准备

    要实践这个技法,你要先装好pandas和xml模块。此外没有要求了。

    2. 怎么做

    从XML文件直接向一个pandas DataFrame对象读入数据需要些额外的代码:这是由于XML文件有特殊的结构,需要针对性地解析。接下来的章节,我们会详细解释这些方法。源代码可在read_xml.py文件中找到:

    import pandas as pd

    import xml.etree.ElementTree as ET

    def read_xml(xml_tree):

    '''

    读入XML数据,返回pd.DataFrame

    '''

    def iter_records(records):

    '''

    遍历所有记录的生成器

    '''

    def write_xml(xmlFileName, data):

    '''

    以XML格式保存数据

    '''

    def xml_encode(row):

    '''

    以特定的嵌套格式将每一行编码成XML

    '''

    # 读出和写入数据的文件名

    r_filenameXML = '../../Data/Chapter01/realEstate_trans.xml'

    w_filenameXML = '../../Data/Chapter01/realEstate_trans.xml'

    # 读取数据

    xml_read = read_xml (r_filenameXML)

    # 打印头10行记录

    print (xml_read.head(10))

    # 以XML格式写回到文件

    write_xml(w_filenameXML, xml_read)

    3. 原理

    我们一步步分析前面的代码。首先引用需要的模块。xml.etree.ElementTree是一个轻量级XML解析器,我们用它来解析文件的XML结构。和之前一样,分别将读取和写入的文件名定义为变量(r_filenameXML,w_filenameXML)。

    使用read_xml(...)方法从XML文件读取数据:

    def read_xml(xmlFileName):

    with open(xmlFileName, 'r') as xml_file:

    # 读取数据,以树的结构存储

    tree = ET.parse(xml_file)

    # 访问树的根节点

    root = tree.getroot()

    # 返回DataFrame

    return pd.DataFrame(list(iter_records(root)))

    这个方法只消传入文件名这一个参数。首先,打开文件。使用.parse(...)方法,我们由XML文件创建了一个树状结构并存入tree对象。接着,在tree对象上用.getroot()方法提取根节点:这是进一步处理数据的前提。最后一行调用iter_records方法,传入根节点的引用,进而将返回的信息转换成DataFrame:

    def iter_records(records):

    for record in records:

    # 保存值的临时字典

    temp_dict = {}

    # 遍历所有字段

    for var in record:

    temp_dict[

    var.attrib['var_name']

    ] = var.text

    # 生成值

    yield temp_dict

    iter_records方法是一个生成器:顾名思义,这个方法生成一些值。普通方法结束时(return语句)一次性返回所有的值;生成器不同,每次只向调用方返回一个值(即yield关键字),直到结束。

    更深入地讨论生成器,建议阅读

    • https://www.jeffknupp.com/blog/2013/04/07/improve-your-python-yield-and-generators-explained/

    我们的iter_records方法,每读入一行,就返回一个temp_dict字典对象给read_xml方法。字典中每个元素的键名对应XML中<var>元素的var_name属性。(<var>有这样的格式:<var var_name=...>。)

    <var>标签可能有其它名字的属性——这些属性会存在.attrib字典(XML树节点一个属性)并通过各自的名字访问——参考代码中高亮的部分。

    <var>的值(<var>...</var>内的部分)可通过XML节点的.text属性访问,而.tag属性存储其名字(这个例子中就是var)。

    read_xml方法的return语句从传入的所有字典中创建一个列表,转换成DataFrame。

    我们使用write_xml(...)方法,以XML格式写入数据:

    def write_xml (xmlFileName, data):

    with open (xmlFileName, 'w') as xmlFile:

    # 写头部

    xmlFile.write(

    '<?xml version="1.0" encoding="UTF-8"?>\n'

    )

    xmlFile.write('<records>\n')

    # 写数据

    xmlFile.write(

    '\n'.join(data.apply(xml_encode, axis=1))

    )

    # 写尾部

    xmlFile.write('\n</records>')

    这个方法打开xmlFileName参数指定的文件。每个XML文件需要以XML声明开头(参考本技法的导论)。接着,我们写了XML schema的根节点,<records>。

    接下来就是写数据。使用DataFrame对象的.apply(...)方法遍历内部每一行。第一个参数指定了要应用到每行记录上的方法。axis参数的默认值为0。意味着指定的方法会应用到DataFrame的每一列上。指定为1,我们让.applay(...)方法将指定的xml_encode(...)方法应用到DataFrame的每一行上。使用xml_encode(...)方法处理data DataFrame的每一行:

    def xml_encode(row):

    # 第一步——输出record节点

    xmlItem = ['<record>']

    # 第二步——给行中每个字段加上XML格式<field name=…>…</field>

    for field in row.index:

    xmlItem \

    .append(

    ' <var var_name=“{0}”>{1}</var>' \

    .format (file, row[field])

    )

    # 最后一步——标记record节点的结束标签

    xmlItem.append('</record>')

    # 返回一个字符串

    return '\n'.join(xmlItem)

    代码生成了一个字符串列表,xmlItem。列表的首元素是<record>,尾元素是</record>。对行中每个字段,我们以<var var_name=<column_name>><value></var>的格式封装,并加进字符串列表。加粗部分指的是列名(<column_name>)和对应的值(<value>)。

    解析完所有字段后,使用'\n'.join(...)方法,将xmlItem列表中所有项连接成一个长字符串。<var>...</var>标签之间以\n分隔。这个字符串被返回给调用方(write_xml)。记录在write_xml(...)方法中进一步连接,并输出到文件。最后加上闭合标签</records>,大功告成。

    05 用pandas解析HTML页面

    尽管以前面介绍的格式保存数据是最常见的,我们有时还是要在网页表格中查找数据。数据的结构通常包含在<table> </table>标签内。本技法会介绍如何从网页获取数据。

    1. 准备

    要实践这个技巧,你要先装好pandas和re模块。re是Python的正则表达式模块,我们用它来清理列名。另外,使用pandas 的read_html(...)方法要预装html5lib模块。如果你使用的是Anaconda发行版Python,使用下面的命令就可以:

    conda install html5lib

    如果不是,你可以从

    • https://github.com/html5lib/html5lib-python

    下载源代码。解压,手动安装模块:

    cd html5lib-python-parserpython setup.py install

    此外没有要求了。

    2. 怎么做

    pandas可以很方便地访问、提取、解析HTML文件。两行代码就能搞定。retrieve_html.py可不止两行,这些我们下一环节再讨论:

    # 要调用的url

    url = 'https://en.wikipedia.org/wiki/' + \

    'List_of_airports_by_IATA_code:_A'

    # 从HTML提取数据

    url_read = pd.read_html (url, header = 0)[0]

    3. 原理

    pandas 的read_html(...)方法解析HTML文件的DOM结构,从所有table节点中提取数据。第一个参数可以是URL、文件或HTML标签原始字符串。第二个参数指定header = 0,忽略了表头。

    read_html(...)方法返回了一个DataFrame对象的列表,每项对应于HTML文件中一个table。Wikipedia的机场页面只包含了一个table,所以我们只要取DataFrame列表的首元素。是的,就是这样!机场列表已经在url_read对象中了。

    拿到的数据还有两点瑕疵:列名包含空白字符,数据包含分隔行。对于名字中可能包含多种空白字符(空格符、制表符等)的问题,我们使用re模块:

    import re

    # 匹配字符串中任意空白字符的正则表达式

    space = re.compiler(r'\s+')

    def fix_string_spaces (columnsToFix):

    '''

    将列名中的空白字符换成下划线

    '''

    tempColumnNames = [] # 保存处理后的列名

    # 循环处理所有列

    for item in columnsToFix:

    # 匹配到

    if space.search (item):

    # 处理并加入列表

    tempColumnNames \

    .append('_'.join (space.split (item)))

    else:

    # 否则直接加入列表

    tempColumnNames.append (item)

    return tempColumnNames

    首先,编译那个匹配出至少一个空白字符的正则表达式。

    对正则表达式的详细讨论超出了本书的知识范围。关于这个主题,有个知识手册写得挺好的:

    • https://www.packtpub.com/application-development/mastering-python-regular-expressions

    或者参考re模块的文档:

    • https://docs.python.org/3/library/re.html

    然后循环处理列,找到空白字符(space.search(...))时,将列名拆开(space.split(...))存入列表。以’_’为间隔,连接列表元素。如果不含空白字符,就将原始列名加入列表。使用下面这行代码处理DataFrame中的列名:

    url_read.columns = fix_string_spaces (url_read.columns)

    查看Wikipedia上的机场表,你会发现它根据前两个字母分组,组与组之间有分隔行。分隔行中缺失了其它列。为了处理这个问题,我们使用DataFrame的.dropna (...)方法。

    pandas有多种方法用于处理NaN(Not a Number)情况。估算缺失值会介绍.fillna (...)方法。

    .dropna (...)方法删掉缺少任意字段数据的行(或者列)。调用.dropna (...)时很容易不传任何参数,这样即便是合理的行,只要缺了夏时制(Daylight Saving Time, DST)或国际民航组织机场代码,也会被删掉。我们可以设道门槛。

    粗粗浏览下数据可以发现,有些合理的行最多会缺两个字段。参数inplace=True直接在原来的DataFrame对象上移除数据,而非复制出一个DataFrame、清理后再返回;默认值是inplace=False:

    url_read.dropna (thresh=2, inplace=True)

    移除一些行后,DataFrame的索引会产生空洞。可以使用这行代码:

    url_read.index = range (0, len(url_read))

    下面这行代码输出头10行IATA代码及对应的机场名:

    print (url_read.head (10)[['IATA', 'Airport_name']])

    如果想取出不止一列,可以以列表的形式传入;在我们的例子中,就是['IATA', 'Airport_name']。下面的代码是等效的:

    print (url_read[0:10] [['IATA', 'Airport_name']])

    关于作者:托马兹·卓巴斯(Tomasz Drabas)微软数据科学家,致力于解决高维特征空间的问题。他有超过13年的数据分析和数据科学经验:在欧洲、澳大利亚和北美洲三大洲期间,工作领域遍及高新技术、航空、电信、金融和咨询。

    本文摘编自《数据分析实战》,经出版方授权发布。

    延伸阅读《数据分析实战》

    推荐语:通过大量的现实案例,详细讲解数据分析相关的各种方法。