python爬虫系列(五)最受欢迎的数据抽取神器学习,一篇就够了。

  发布日期:   2017-09-12
  最新修改:   2020-04-08
  阅读次数:   96 次

一、前言:

  • 现在到处都在说大数据,机器学习,深度学习。
  • 然后数据是哪里来的呢?要么你是bat这类公司,手握大量数据,一般情况下,我们都是需要通过一些必要的手段来获取数据。
  • 而说到获取数据,就离不开我们的网络爬虫,也有叫网络蜘蛛之类的等等,但本质就是一个不断从从Internt上下载数据的程序。
  • 数据下载之后是很原始的数据,此时我们接下来当然是从数据中筛选出对我们有用的数据了。
  • 此时常用的方式有使用正则、css、或者xpath等锁定目标数据并抽取出来。

二、lxml与XPath

  • Lxml 是基于libxml2库的Python封装。lxml使用C语言编写,解析速度比Beautiful Soup更快,最新版本的lxml支持CPython2.6至3.6的版本。
  • Lxml也是唯一支持解析XMl的库哦。
  • XPath即为XML路径语言,它是一种用来确定XML文档中某部分位置的语言,也就是说可以用来表示xml文档中的某个节点部分。
  • XPath基于XML的树状结构,提供在数据结构树中找寻节点的能力。而我们抓取下来的数据如果是html,此时一般我们可以先将html通过某鞋工具库转换为xml结构的数据。
  • 转换好之后当然就可以愉快的用我们的xpath语法进行数据抽取了。
  • 其实我是很喜欢xpath的,因为其编写的代码简洁,功能强大。

三、lxml学习教程

  • 本次学习我们将采用lxml库来进行操作。
  • lxml库作为python第三方库中最受欢迎的库,其底层采用C语言进行编写从而给使用者带来极好的解析速度体验。

    lxml的安装

  • python3安装:pip3 install lxml

    lxml.etree处理xml

  • 1、首先我们先导入etree
    • from lxml import etree

Element 类:

  • Element是ElementTree API的主要容器对象。大多数XML树功能都是通过这个类访问的。Element可以通过Element工厂轻松创建:

    • root = etree.Element('root');
  • 我们你可以通过访问Element的tag属性获取元素的标签名称

    • root.tag -> root
  • Element以XML树结构进行组织数据。要创建子元素并将其添加到父元素中,可以使用append()方法:

    • root.append( etree.Element("child1") );
  • 我们还可以用一个更短的和更有效的方法来做到这一点:SubElement工厂。它接受与元素工厂相同的参数,但要求父节点作为第一个参数:

    • child2 = etree.SubElement(root, "child2");
    • child3 = etree.SubElement(root, "child3");
Elements列表
  • 我们创建的root等元素其实是一个列表累的哦

  • 我们可以这样访问创建的child2的元素名称

    • root[0].tag
  • 获取root的子元素长度

    • len(root)
  • 判断子元素的父元素

    • root is root[0].getparent();
  • 判断一个元素是否在其兄弟元素的前面

  • 我们这里的child1和child2即为兄弟元素

    • 判断root[0]是否是root[1]的前一个元素
    • root[0] is root[1].getprevious()
    • 判断root[1]是否是root[0]的后一个元素
    • root[1] is root[0].getnext()
元素携带的属性
  • 元素所携带的属性将以字典的形式进行存储,以下我们为root添加一个class属性

    • root = etree.Element('root',attrib={'class':'hello'});
    • 打印结果为:
    • <root class="hello"/>
  • 我们也可以在创建了元素之后添加属性:

    • root.set('id',world);
    • 打印结果为:
    • <root class="hello" id="world"/>
  • 设置属性之后,我们想要读取属性也是非常容易的。

    • root.get('class');
    • 输出为:hello
  • 我们可以通过keys()方法获取元素的所有属性集合,其以列表的形式返回给我们

    • root.keys();
    • 输出为:['class', 'id']
  • 我们可以通过values()方法获取元素的所有属性对应的值的集合,其以列表的形式返回给我们

    • root.values();
    • 输出为:['hello', 'world']
  • items()则以元组列表的形式返回所有的属性集合:

    • root.items();
    • 输出结果为:[('class', 'hello'), ('id', 'world')]
  • 元素的attrib属性负责存储我们的属性集合,我们也可以直接取出来进行设置

    • at = root.attrib;
    • at['class']='hello';
    • root.set('class','hello')两者是等价的

Text

  • 元素的text属性存储了元素的内容。

  • 如我们需要在创建<title>hello</title>

    • root = etree.Element("root");
    • root.text='hello';
    • print(etree.tostring(root,pretty_print=True))
    • 输出为:<title>hello</title>
  • 以上也部分证明了root其实是一个列表哦。

xpath抽取内容

  • 我们可以使用元素自身提供的xpath去获取title内部的内容,结果以列表的形式返回

    • root.xpath('//title/text()');
    • 输出为:['hello']
  • 我们还可以判断获取的内容是不是text

    • text = root.xpath('//text()');
    • print(text[0].is_text)
    • 输出内容为:True

元素的迭代

  • 我们有时候希望遍历整个文档的内容,for in语句当然是我们最常用的了。
  • lxml的元素本身也提供了迭代的能力
    • root = etree.Element("root")
    • etree.SubElement(root, "child").text = "Child 1"
    • etree.SubElement(root, "child").text = "Child 2"
    • etree.SubElement(root, "another").text = "Child 3"
    • for element in root.iter():print("%s - %s" % (element.tag, element.text))
    • 结果输出为 root - None child - Child 1 child - Child 2 another - Child 3

fromstring() 、 XML()、HTML()

  • 我们解析的文本有可能是一个本地文件,也有可能是网上请求的一个string,一般我们可以使用fromstring()和XML()两个方法来加载需要解析的数据。
  • 当然,一般如果你是用在爬虫项目中,可能更多的就是使用HTML()方法了
  • 示例代码:

29428c3a7c4c4b82b2ac0b552532b9ae-1.png

  • 结果输出为:

0341ccb0b0e1461f85d7a13a6e58ee50-1.png

  • 结果解析,我们可以看到,HTML()返回的是一个html类型的Element元素。其内部帮我们增加了html必备的html元素和body元素。

xpath进阶学习

  • 在进一步学习xpath之前,我贴两张网上收集的非常好的使用学习资料

bc85b05a64a34c18b4f2f3e3ca18c670-1.png

76e61eed05034ecf8dd5084a3afa9ae9-1.png

  • OK,我们根据上面的示例代码,通过从中获取div、ul、li等标签来学习xpath的使用技巧。

  • 获取div标签

    • div_tag = root.xpath('//div')
    • print(div_tag)
    • 打印输出为:[<Element div at 0x10b681f88>]
  • 获取ul标签

    • ul_tag = root.xpath('//div/ul')
    • print(ul_tag)
    • 打印输出为:[<Element ul at 0x10bdfde48>]
  • 获取li标签:

    • li_tag = root.xpath('//div/ul/li')
    • print(li_tag)
    • [<Element li at 0x10bdfdd48>, <Element li at 0x10bdfdec8>, <Element li at 0x10bdfdf08>, <Element li at 0x10bdfdf48>]
  • 从上面三个示例可以看到,其返回结果为我们xpath表达式定位的标签列表。

  • 返回的数据均为Element元素,这样保证了我们的抽取结果可以继续使用Element类的能力,你可以通过Elementapi继续抽取数据,也可以继续通过xpath继续抽取数据。

  • 我们也可以直接获取带某个属性的元素集合:

    • class_tag = root.xpath('//@class')
    • print(class_tag)
    • 结果输出为:['item-0', 'item-1', 'item-2', 'item-3']
  • 如此我们便获取了带class属性的值集合。

  • 我们来获取class="item-0"下面的a标签

    • li1 = root.xpath('//div/ul/li[@class="item-0"]/a');
    • print(li1)
    • [<Element a at 0x10c4a1048>]
  • 当然,我们也可以换个方式,我们获取href="link1.html"的a标签

    • li1 = root.xpath('//li/a[@href="link1.html"]');
    • print(li1)
    • [<Element a at 0x10f5aa048>]
  • 获取最后一个li标签里面的a标签的href属性的值

    • href_value = root.xpath('//li[last()]/a/@href');
    • print(href_value)
    • ['link4.html']
  • 通过上面实例的练习,相信大家对 XPath 的基本用法有了基本的了解。

  • 大家可以根据实际情况继续深入学习。

  • XPath 是一个非常好用的解析方法,同时也作为爬虫学习的基础,小编很喜欢。在后面的爬虫抽取数据部分会经常用到。


   转载规则

《python爬虫系列(五)最受欢迎的数据抽取神器学习,一篇就够了。字》GajAngels 采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可。