网页数据抓取软件(如何把它输入给lxml.html模块(html字符串) )
优采云 发布时间: 2021-10-14 00:21网页数据抓取软件(如何把它输入给lxml.html模块(html字符串)
)
狭义的爬虫只负责爬行,也就是下载网页。实际上,爬虫也负责从下载的网页中提取我们想要的数据,即对非结构化数据(网页)进行分析,提取结构化数据(有用数据)。比如我们想要抓取一个新闻页面的网页(html),但是我们想要的是这个网页中关于新闻的结构化数据:新闻标题、新闻发布时间、新闻正文等。
因此,下载网页只是第一步,另一个重要的步骤是数据提取。不同的爬虫想要的数据不同,提取的数据也不同,但是提取的方法大同小异。
提取数据的最简单方法是使用正则表达式。这种方法简单,提取逻辑不能复杂,否则写的正则表达式会晦涩难懂,甚至复杂的数据结构也提取不出来。
最后,经过多年的经验,老袁选择了lxml和xpath来解析网页,提取结构化数据。顺便说一句,BeautifulSoup 也是解析 HTML 的好工具。可以使用多个解析器,比如Python标准库的解析器,但是速度比较慢。也可以使用 lxml 作为解析器,但它的用法和 API 与 lxml 不一样。用了之后,lxml的API就舒服多了。
lxml 绑定了 C 语言库 libxml2 和 libxslt,并提供了 Pythonic API。它有一些主要特点:
一句话概括,是一个结合了C语言的速度和Python的简单性的神器。
lxml有两部分,分别支持XML和HTML的解析:
lxml.etree 可以用来解析RSS feed,它是一个XML 格式的文档。但是爬虫爬取的大部分都是html网页,所以这里主要讲一下lxml.html解析网页的方法。
lxml.html 从 html 字符串生成文档树结构
我们下载的网页是一串html字符串。如何将其输入到 lxml.html 模块中以生成 html 文档的树结构?
该模块提供了几种不同的方法:
下面我们通过具体的例子来说明上述方法的区别。
如何使用 document_fromstring
In [1]: import lxml.html as lh
In [2]: z = lh.document_fromstring('abcxyz')
# 可以看到,它自动加了根节点
In [3]: z
Out[3]:
In [4]: z.tag
Out[4]: 'html'
# 还加了节点
In [5]: z.getchildren()
Out[5]: []
# 把字符串的两个节点放在了里面
In [6]: z.getchildren()[0].getchildren()
Out[6]: [, ]
fragment_fromstring 的使用
In [11]: z = lh.fragment_fromstring(‘abcxyz’)
---------------------------------------------------------------------------
ParserError Traceback (most recent call last)
in ()
----> 1 z = lh.fragment_fromstring(‘abcxyz’)
~/.virtualenvs/py3.6/lib/python3.6/site-packages/lxml/html/__init__.py in fragment_fromstring(html, create_parent, base_url, parser, **kw)
850 raise etree.ParserError(
851 “Multiple elements found (%s)”
--> 852 % ‘, ‘.join([_element_name(e) for e in elements]))
853 el = elements[0]
854 if el.tail and el.tail.strip():
ParserError: Multiple elements found (div, div)
# 可以看到,输入是两个节点(element)时就会报错
# 如果加上 create_parent 参数,就没问题了
In [12]: z = lh.fragment_fromstring('abcxyz', create_parent='p')
In [13]: z.tag
Out[13]: 'p'
In [14]: z.getchildren()
Out[14]: [, ]
fragment_fromstring 的使用
# 输入字符串含有一个节点,则返回包含这一个节点的列表
In [17]: lh.fragments_fromstring('abc')
Out[17]: []
# 输入字符串含有多个节点,则返回包含这多个节点的列表
In [18]: lh.fragments_fromstring('abcxyz')
Out[18]: [, ]
使用 fromstring
<br />In [27]: z = lh.fromstring('abcxyz')
In [28]: z
Out[28]:
In [29]: z.getchildren()
Out[29]: [, ]
In [30]: type(z)
Out[30]: lxml.html.HtmlElement
这里,如果输入的fromstring是多个节点,则会添加一个父节点并返回。但是就像html网页从节点开始一样,我们可以使用fromstring()和document_fromstring()来获取完整的网页结构。
从上面的代码中,我们可以看到这些函数返回的是 HtmlElement 对象。也就是说,我们已经学会了如何从 html 字符串中获取 HtmlElement 对象。在下一节中,我们将学习如何操作 HtmlElement 对象。提取我们感兴趣的数据。