整合营销服务商

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

免费咨询热线:

Python如何解析HTML和XML数据

一篇我们介绍了如何解析CSV和JSON数据:如何解析互联网数据:CSV和JSON篇,今天我们将介绍如何解析HTML和XML数据。

今天的介绍能够帮助你轻而易举地从网页中(比如下面的中航电子的2017年一季度交易数据)提取自己想要的数据:

准备

在Python中可以解析html和xml数据的软件包很多,今天我们介绍的是lxml,先安装:

$ pip install lxml

如果不熟悉pip的使用,可以参考另一篇文章:如何管理python软件包。

解析HTML数据

首先,回顾一下HTML的一些基本概念:

  • 标签/tag:比如<html>, <h1>, <head>...一般成对出现,例如开始标签<html>和结束标签</html>

  • 元素/element:开始标签到结束标签整段代码,标签对之间的即为内容(content)

  • 属性/attribute:标签可拥有key=value形式的属性,比如<div class="header">...</div>

简单地理解,HTML网页就是由一组元素构成的一个集合。另外,大多数HTML标签是可以嵌套的,因此元素可以包含一系列子元素。有了这些概念做基础,我们将能够很容易理解软件包lxml的使用。实际上,在lxml里面,每个HTML元素对应一个lxml.html.HtmlElement对象,该对象提供一组标准的方法取访问包含在该元素内部的数据,比如属性、内容和子元素等。

例子

考察下面的链接,它提供中航电子在2017年第一季度的交易数据,我们打算从里面提取一些数据:

>>> url = "http://quotes.money.163.com/trade/lsjysj_600372.html?year=2017&season=1"

先把该网页爬取下来:

>>> import urllib2

>>> rsp = urllib2.urlopen(url).read()

>>> print rsp[0:15]

<!DOCTYPE html>

将字符串rsp转换成HtmlElement对象:

>>> from lxml import html

>>> doc = html.document_fromstring(rsp)

>>> type(doc)

<class 'lxml.html.HtmlElement'>

>>> doc.tag

'html'

所以其实doc就是一个html元素,它包含一些元素,比如head, body, link, div...

比如,如果你想提取该网页里面所有的链接(links):

>>> links = [ link for link in doc.iterlinks() ]

>>> len(links)

106

>>> links[0]

(<Element link at 0x1029179f0>, 'href', 'http://img1.cache.netease.com/f2e/finance/gegu/s.1064000.css', 0)

>>> links[0][2]

'http://img1.cache.netease.com/f2e/finance/gegu/s.1064000.css'

如果你想查看元素直接包含哪些子元素,可以调用getchildren()方法:

>>> doc.getchildren()

[<Element head at 0x10299a0a8>, <Element body at 0x10299a470>]

对嵌套很深的元素,如果熟悉xpath表达式,最直接的办法是调用xpath(...)方法:

>>> [ td.text for td in doc.xpath('/html/body/div[2]/div[4]/table/tr[1]/td')]

['2017-03-31', '19.02', '19.50', '19.02', '19.30', '0.36', '1.90', '102,212', '19,747', '2.53', '0.58']

此外,还可以通过find, findall, find_class, get_element_by_id等方法查找目标元素,比如:

>>> [ td.text for td in doc.findall('./body/div[2]/div[4]/table/tr[1]/td')]

['2017-03-31', '19.02', '19.50', '19.02', '19.30', '0.36', '1.90', '102,212', '19,747', '2.53', '0.58']

如果元素有属性,提取属性值也很方便,比如:

>>> form = doc.forms[0]

>>> form.tag

'form'

>>> form.attrib

{'action': '/trade/lsjysj_600372.html', 'id': 'date'}

>>> form.keys()

['id', 'action']

>>> form.get('action')

'/trade/lsjysj_600372.html'

>>> form.items()

[('id', 'date'), ('action', '/trade/lsjysj_600372.html')]

'>>> form.form_values()

[('year', '2017'), ('season', '1')]

>>> form.method

'GET'

做为一个完整的例子,下面的脚本就是爬取中航电子在2017年第一季度的数据:

输出效果:

(test) $ head -3 600372.csv

日期;开盘价;最高价;最低价;收盘价;涨跌额;涨跌幅(%);成交量(手);成交金额(万元);振幅(%);换手率(%)

2017-03-31;19.02;19.50;19.02;19.30;0.36;1.90;102,212;19,747;2.53;0.58

2017-03-31;19.02;19.50;19.02;19.30;0.36;1.90;102,212;19,747;2.53;0.58

解析xml数据

xml的格式和HTML类似,也是由标签构成的,但是要比HTML文件简单许多,看下面的xml文件片段处理:

>>> xmlstr="""\

... <target name="run" depends="jar">

... <java fork="true" classname="${main-class}">

... <classpath>

... <path refid="classpath"/>

... <path refid="application"/>

... </classpath>

... </java>

... </target>"""

>>> from lxml import etree

第一步是获取根节点:

>>> root = etree.fromstring(xmlstr)

>>> root.tag

'target'

如果要提取节点属性:

>>> root.items()

[('name', 'run'), ('depends', 'jar')]

>>> root.keys()

['name', 'depends'

>>> root.get("name")

'run'

>>> root.values()

['run', 'jar']

可以使用find, xpath等方法去获取和查找子节点:

>>> java = root.find("./java")

>>> java.tag

'java'

>>> java.keys()

['fork', 'classname']

>>> [ path.get("refid") for path in root.xpath("//path")]

['classpath', 'application']

lxml软件的功能很强大,如果有兴趣进一步了解,可以查看官方文档:

http://lxml.de/index.html

今天就写这么,欢迎大家留言、评论和关注。


tmlAgilityPack是一个.NET平台下的HTML解析库,它可以将HTML文本转换为DOM文档对象,方便我们对HTML文本进行操作和分析。HtmlAgilityPack支持XPath语法,可以通过XPath表达式来获取DOM节点,同时还提供了一些方便的API,可以实现HTML文本的解析、修改、生成等功能。本文将详细介绍HtmlAgilityPack的使用及使用方法。

一、HtmlAgilityPack的安装

HtmlAgilityPack是一个NuGet包,可以通过Visual Studio的NuGet包管理器来安装。具体步骤如下:

  1. 打开Visual Studio,打开要安装HtmlAgilityPack的项目。
  2. 在“解决方案资源管理器”中右键单击项目,选择“管理NuGet程序包”。
  3. 在“NuGet程序包管理器”中搜索“HtmlAgilityPack”,选择“安装”。
  4. 等待安装完成。

安装完成后,就可以在项目中使用HtmlAgilityPack了。

二、HtmlAgilityPack的使用

  1. 加载HTML文本

使用HtmlAgilityPack解析HTML文本的第一步是将HTML文本加载到一个HtmlDocument对象中。可以通过以下代码来实现:

HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(htmlText);

其中,htmlText是要解析的HTML文本。LoadHtml方法会将HTML文本解析成一个DOM文档对象,并存储在doc对象中。

  1. 获取DOM节点

HtmlAgilityPack提供了一些方法来获取DOM节点,例如GetElementById、GetElementsByTagName、SelectSingleNode、SelectNodes等。这些方法都接受一个XPath表达式作为参数,用来指定要获取的节点。以下是一些示例代码:

// 获取id为"content"的节点
HtmlNode contentNode = doc.GetElementById("content");

// 获取所有的a标签
HtmlNodeCollection aNodes = doc.DocumentNode.SelectNodes("//a");

// 获取第一个p标签
HtmlNode pNode = doc.DocumentNode.SelectSingleNode("//p");

其中,XPath表达式的语法与XML的XPath语法相同。在这里不再详细介绍。

  1. 修改DOM节点

HtmlAgilityPack提供了一些方法来修改DOM节点,例如SetAttributeValue、InnerHtml、OuterHtml等。以下是一些示例代码:

// 修改id为"content"的节点的class属性
contentNode.SetAttributeValue("class", "new-class");

// 修改第一个p标签的内容
pNode.InnerHtml = "这是新的内容";

// 修改第一个a标签的href属性
HtmlNode aNode = aNodes[0];
aNode.SetAttributeValue("href", "http://www.example.com");
  1. 生成HTML文本

HtmlAgilityPack还可以将DOM文档对象转换为HTML文本。可以通过以下代码来实现:

string newHtmlText = doc.DocumentNode.OuterHtml;

其中,OuterHtml属性返回DOM文档对象的HTML文本表示。

三、HtmlAgilityPack的功能实例

下面将通过一些具体的实例来演示HtmlAgilityPack的使用方法。

  1. 获取页面标题

以下代码演示了如何获取页面标题:

HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(htmlText);

HtmlNode titleNode = doc.DocumentNode.SelectSingleNode("//title");
string title = titleNode.InnerHtml;

其中,htmlText是要解析的HTML文本。首先,将HTML文本加载到一个HtmlDocument对象中。然后,通过XPath表达式“//title”获取页面标题节点。最后,通过InnerHtml属性获取标题的内容。

  1. 获取页面中的所有图片

以下代码演示了如何获取页面中的所有图片:

HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(htmlText);

HtmlNodeCollection imgNodes = doc.DocumentNode.SelectNodes("//img");
foreach (HtmlNode imgNode in imgNodes)
{
    string src = imgNode.GetAttributeValue("src", "");
    Console.WriteLine(src);
}

首先,将HTML文本加载到一个HtmlDocument对象中。然后,通过XPath表达式“//img”获取所有图片节点。最后,遍历所有图片节点,获取每个节点的src属性。

  1. 获取页面中的所有链接

以下代码演示了如何获取页面中的所有链接:

HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(htmlText);

HtmlNodeCollection aNodes = doc.DocumentNode.SelectNodes("//a");
foreach (HtmlNode aNode in aNodes)
{
    string href = aNode.GetAttributeValue("href", "");
    Console.WriteLine(href);
}

首先,将HTML文本加载到一个HtmlDocument对象中。然后,通过XPath表达式“//a”获取所有链接节点。最后,遍历所有链接节点,获取每个节点的href属性。

  1. 修改页面中的所有链接

以下代码演示了如何将页面中的所有链接修改为指定的链接:

HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(htmlText);

HtmlNodeCollection aNodes = doc.DocumentNode.SelectNodes("//a");
foreach (HtmlNode aNode in aNodes)
{
    aNode.SetAttributeValue("href", "http://www.example.com");
}

string newHtmlText = doc.DocumentNode.OuterHtml;

首先,将HTML文本加载到一个HtmlDocument对象中。然后,通过XPath表达式“//a”获取所有链接节点。最后,遍历所有链接节点,将它们的href属性修改为指定的链接。最后,通过OuterHtml属性将修改后的DOM文档对象转换为HTML文本。

本文介绍了HtmlAgilityPack的使用及使用方法。HtmlAgilityPack是一个功能强大、易用性高的HTML解析库,可以方便地对HTML文本进行操作和分析。通过本文的介绍,读者可以了解HtmlAgilityPack的基本用法,并可以根据需要自行扩展。


行期文章:

【大厂面试】Java中的序列化和反序列化它们的作用和用途是什么?

.net core下优秀的日志框架使用解析,附源代码

Spring Boot+Vue全栈开发实战,中文版高清PDF资源


作者简介:
【架构师老卢】20年资深软件架构师,分享编程、软件设计经验,教授前沿技术,分享技术资源,分享职场感悟

据分析常用哪些Python包?这里将其总结如下,比如在数据清洗时使用到numpy和pandas包,数据可视化时使用matplotlib库,matplotlib库上手容易,更高级的学习seaborn库,seaborn库是改良matplotlib库的图表画法,如果创建有交互性的图表,可以使用Pyecharts库。

Python的作用绝不仅仅只是做数据清洗和数据可视化,其作用还有很多,有许多意想不到的功能,这里仅仅举例讲讲Python在数据分析中使用最多的几个包,欢迎大家补充,下面一起来学习。

1、Numpy

官网https://www.numpy.org.cn/

NumPy是Python中科学计算的基础包。它是一个Python库,提供多维数组对象,各种派生对象,以及用于数组快速操作的各种API,有包括数学、逻辑、形状操作、排序、选择、输入输出、离散傅立叶变换、基本线性代数,基本统计运算和随机模拟等等。

NumPy包的核心是 ndarray 对象。它封装了python原生的同数据类型的 n 维数组,为了保证其性能优良,其中有许多操作都是代码在本地进行编译后执行的。

NumPy的主要对象是同构多维数组。它是一个元素表,所有类型都相同,由非负整数元组索引。在NumPy维度中称为轴 。

2、Pandas

官网https://www.pypandas.cn/

Pandas 是 Python的核心数据分析支持库,提供了快速、灵活、明确的数据结构,旨在简单、直观地处理关系型、标记型数据,广泛应用于数据分析领域,Pandas 适用于处理与 Excel 表类似的表格数据,以及有序和无序的时间序列数据等。

Pandas 的主要数据结构是 Series(一维数据)和 DataFrame(二维数据),这两种数据结构足以处理金融、统计、社会科学、工程等领域里的大多数典型用例,使用pandas进行数据分析流程包含数据整理与清洗、数据分析与建模、数据可视化与制表等阶段。

  • 灵活的分组功能:(group by)数据分组、聚合、转换数据;
  • 直观地合并功能:(merge)数据连接;
  • 灵活地重塑功能:(reshape)数据重塑;

3、Matplotlib

官网https://www.matplotlib.org.cn/

Matplotlib是一个Python 2D绘图库,它以多种硬拷贝格式和跨平台的交互式环境生成出版物质量的图形。Matplotlib可用于Python脚本,Python和IPython Shell、Jupyter笔记本,Web应用程序服务器和四个图形用户界面工具包。

Matplotlib 尝试使容易的事情变得更容易,使困难的事情变得可能,只需几行代码就可以生成图表、直方图、功率谱、条形图、误差图、散点图等。

为了简单绘图,该 pyplot 模块提供了类似于MATLAB的界面,尤其是与IPython结合使用时,对于高级用户,您可以通过面向对象的界面或MATLAB用户熟悉的一组功能来完全控制线型,字体属性,轴属性等。

4、Seaborn

官网http://seaborn.pydata.org/

Seaborn 是一个基于matplotlib的 Python 数据可视化库,它建立在matplotlib之上,并与Pandas数据结构紧密集成,用于绘制有吸引力和信息丰富的统计图形的高级界面。

Seaborn 可用于探索数据,它的绘图功能对包含整个数据集的数据框和数组进行操作,并在内部执行必要的语义映射和统计聚合以生成信息图,其面向数据集的声明式 API可以专注于绘图的不同元素的含义,而不是如何绘制它们的细节。

Matplotlib 拥有全面而强大的 API,几乎可以根据自己的喜好更改图形的任何属性,seaborn 的高级界面和 matplotlib 的深度可定制性相结合,使得Seaborn既可以快速探索数据,又可以创建可定制为出版质量最终产品的图形。

5、Pyecharts

官网https://pyecharts.org/#/

Echarts 是一个由百度开源的数据可视化,凭借着良好的交互性,精巧的图表设计,得到了众多开发者的认可。而 Python 是一门富有表达力的语言,很适合用于数据处理。当数据分析遇上数据可视化时,pyecharts 诞生了。

Pyecharts具有简洁的 API 设计,使用如丝滑般流畅,支持链式调用,囊括了 30+ 种常见图表,应有尽有,支持主流 Notebook 环境,Jupyter Notebook 和 JupyterLab,拥有高度灵活的配置项,可轻松搭配出精美的图表。

Pyecharts强大的数据交互功能,使数据表达信息更加生动,增加了人机互动效果,并且数据呈现效果可直接导出为html文件,增加数据结果交互的机会,使得信息沟通更加容易。

Pyecharts有着丰富的图表素材,支持链式调用,如下是使用Pyecharts的地理图表功能,空间上直观显示数据可视化效果。

更多实用的数据分析知识,关注我,持续创作数据分析内容~