python抓取网页数据(Python的lxml模块是什么意思?如何把网页解析成DOM树 )

优采云 发布时间: 2021-09-19 04:04

  python抓取网页数据(Python的lxml模块是什么意思?如何把网页解析成DOM树

)

  Python的lxml模块是一个非常易于使用的高性能HTML和XML解析工具。通过解析网页,爬虫可以轻松地从网页中提取所需的数据。Lxml是基于C语言的libxml2和libxslt库开发的,速度非常快

  

  使用lxml提取web页面数据的过程

  要从网页提取数据,使用lxml需要两个步骤:

  生成DOM树

  如上所述,有三种方法可以将网页解析为DOM树。选择有困难的学生将很难。什么样的好选择?别担心,让我们一个一个地探索。让我通过一个示例分析以下HTML代码:

  

<p class="p_1 item">item_1

  item_2

  item_3

</p>

  使用etree。Fromstring()函数

  让我们看一下这个函数(docstring)的描述:

  In [3]: etree.fromstring?

Signature: etree.fromstring(text, parser=None, *, base_url=None)

Call signature: etree.fromstring(*args, **kwargs)

Type: cython_function_or_method

String form:

Docstring:

fromstring(text, parser=None, base_url=None)

Parses an XML document or fragment from a string. Returns the

root node (or the result returned by a parser target).

To override the default parser with a different parser you can pass it to

the ``parser`` keyword argument.

The ``base_url`` keyword argument allows to set the original base URL of

the document to support relative Paths when looking up external entities

(DTD, XInclude, ...).

  此函数将输入HTML解析为DOM树并返回根节点。它对输入字符串文本有任何要求吗?首先,它必须是合法的HTML字符串,然后让我们来看看下面的例子:

  In [19]: html = '''

...:

...: <p class="p_1 item">item_1

...:

  item_2

...:

...:

...:

  item_3

...:

...: '''

In [20]: etree.fromstring(html)

Traceback (most recent call last):

File "/home/veelion/.virtualenvs/py3.6/lib/python3.6/site-packages/IPython/core/interactiveshell.py", line 3267, in run_code

exec(code_obj, self.user_global_ns, self.user_ns)

File "", line 1, in

etree.fromstring(html)

File "src/lxml/etree.pyx", line 3213, in lxml.etree.fromstring

File "src/lxml/parser.pxi", line 1877, in lxml.etree._parseMemoryDocument

File "src/lxml/parser.pxi", line 1758, in lxml.etree._parseDoc

File "src/lxml/parser.pxi", line 1068, in lxml.etree._BaseParser._parseUnicodeDoc

File "src/lxml/parser.pxi", line 601, in lxml.etree._ParserContext._handleParseResultDoc

File "src/lxml/parser.pxi", line 711, in lxml.etree._handleParseResult

File "src/lxml/parser.pxi", line 640, in lxml.etree._raiseParseError

File "", line 6

XMLSyntaxError: Extra content at the end of the document, line 6, column 1

</p>

  报告错了!原因是我们的html是并置的

  没有单独根节点的标记。然后将最外层添加到HTML

  标签呢

  In [22]: etree.fromstring('' + html + '')

Out[22]:

  这样,将返回根节点,它是一个元素对象,标记是Div

  总而言之,埃特里。Fromstring()需要最外层是单独的节点,否则将发生错误。该方法也适用于生成XML的DOM树

  使用etree。HTML()函数

  这个函数更像HTML。查看其文档字符串:

  In [23]: etree.HTML?

Signature: etree.HTML(text, parser=None, *, base_url=None)

Call signature: etree.HTML(*args, **kwargs)

Type: cython_function_or_method

String form:

Docstring:

HTML(text, parser=None, base_url=None)

Parses an HTML document from a string constant. Returns the root

node (or the result returned by a parser target). This function

can be used to embed "HTML literals" in Python code.

To override the parser with a different ``HTMLParser`` you can pass it to

the ``parser`` keyword argument.

The ``base_url`` keyword argument allows to set the original base URL of

the document to support relative Paths when looking up external entities

(DTD, XInclude, ...).

  就像两颗豌豆(etree.fromstring)一样

  接口参数包括:

  In [24]: etree.HTML(html)

Out[24]:

  为两个并排的节点输入HTML没有问题。等等,返回的根节点对象元素的标记是HTML?使用etree将其还原为HTML代码。Tostring():

  In [26]: print(etree.tostring(etree.HTML(html)).decode())

<p class="p_1 item">item_1

  item_2

  item_3

In [27]: print(html)

  item_1

  item_2

  item_3

</p>

  也就是说,etree。函数完成HTML代码片段并对其进行标记

  使用lxml.html函数

  html是Lxml的一个子模块。它封装了etree,更适合解析HTML网页。使用此子模块生成DOM树有几种方法:

  他们的docstring可以在IPython中进行检查,这里不会列出。通常,我们可以使用最后一个fromstring()解析网页。这个fromstring()函数还将向示例HTML代码的前两个并行节点添加一个父节点div

  在介绍了以上三种方法之后,我相信你有一个选择。它必须是lxml.html

  因为它封装了HTML,所以它还有特殊的编写方法:

  使用XPath提取数据

  我们还以下面的HTML代码为例来了解如何定位节点和提取数据

  

<p class="p_1 item">item_1

  item_2

  item_3

</p>

  首先,导入lxml.html模块以生成DOM树:

  In [50]: import lxml.html as lh

In [51]: doc = lh.fromstring(html)

  (1)通过标记属性定位节点)

  例如,我们需要

  此节点:

  In [52]: doc.xpath('//div[@class="2"]')

Out[52]: []

In [53]: print(lh.tostring(doc.xpath('//div[@class="2"]')[0]).decode())

<p id="p3">item_3

</p>

  (2)contains文法

  HTML中有两种

  标记的类收录项。如果要提取这两个项

  标签,然后:

  In [54]: doc.xpath('//p[contains(@class, "item")]')

Out[54]: [, ]

## 获取<p>的文本:

In [55]: doc.xpath('//p[contains(@class, "item")]/text()')

Out[55]: ['item_1', 'item_2']

  (3)starts-使用语法

  提取需求,如(2)),两个

  标签的类别以p_uSO开头:

  In [60]: doc.xpath('//p[starts-with(@class, "p_")]')

Out[60]: [, ]

## 获取<p>的文本:

In [61]: doc.xpath('//p[starts-with(@class, "p_")]/text()')

Out[61]: ['item_1', 'item_2']

  (4)获取属性的值

  例如,我们希望提取网页中的所有链接:

  In [63]: doc.xpath('//@href')

Out[63]: ['/go-p3']

  如果您对XPath有更聪明的用法,请与我们分享。谢谢

  

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线