美文网首页python 爬虫 spider
爬虫解析库--pyquery以及css选择器的使用

爬虫解析库--pyquery以及css选择器的使用

作者: RevinDuan | 来源:发表于2018-08-29 14:57 被阅读0次

    对于规则的网页信息我们可以使用的解析库和选择器很多比如bs4,xpath 等,这里我们介绍一种css选择器功能非常强大的库--pyquery

    安装

    pip3 install pyquery

    使用

    环境python3

    初始化

    # -*- coding: utf-8 -*-
    from pyquery import PyQuery as pq
    html='''
    <div class="qrcodeCon">
        <div id="qrcode">
            <div class="qrcode-item qrcode-item-1">
                <div class="qrcode-img"></div>
                <div class="qrcode-text">
                        <p><b>百度</b></p>
                </div>
            </div>
        </div>
    </div>
    '''
    
    doc = pd(html) # 这里doc就是一个pyquery对象我们可以对其进行选择器操作,这就是初始化
    print(doc('a'))  # 这里就可以对节点下所有的子孙节点的查找a标签
    
    # 此外还支持url初始化,以及文件初始化
    doc = pd(url = 'https://www.baidu.com')  # url初始化
    print(doc('title'))
    
    doc = pd(filename='test.html')  # 文件初始化
    print(doc('title'))
    

    基本选择器
    还是以上面的文本内容为例:

    from pyquery import PyQuery as pq
    html = '''
    <div class="qrcodeCon">
        <div id="qrcode">
            <div class="qrcode-item qrcode-item-1">
                <div class="qrcode-img"></div>
                <div class="qrcode-text">
                        <p><b>百度</b></p>
                        <a>hello world</a>
                </div>
            </div>
        </div>
    </div>
    
    '''
    doc = pq(html)
    print(doc('.qrcodeCon .qrcode-text').text())
    

    从上面的例子中我们可以看到pyquery的css选择器的用法很简单,给pq对象传入一个查找参数就可以了, # 表示id, . 表示类 下一级就空格一下,这样就可以轻松的定位到我们需要的节点了.

    查找节点
    pyquery 查找子节点的时候可以使用上面我们说的方法也可以使用一下方法:

    • 子节点
      查找子节点的时候,需要用到find()方法,此时传入的参数是css选择器,同样的以上面的文档为例,
    # -*- coding: utf-8 -*-
    from pyquery import PyQuery as pq
    html = '''
    <div class="qrcodeCon">
        <div id="qrcode">
            <div class="qrcode-item qrcode-item-1">
                <div class="qrcode-img"></div>
                <div class="qrcode-text">
                        <p><b>百度</b></p>
                        <a>hello world</a>
                        <a>hello world</a>
                </div>
            </div>
        </div>
    </div>
    
    '''
    doc = pq(html)
    first = doc('.qrcodeCon')
    second = doc.find('.qrcode-text a')
    third = doc('.qrcode-text a')
    print(second)
    print(third)
    

    两个结果是一样的
    <a>hello world</a>
    <a>hello world</a>
    <a>hello world</a>
    <a>hello world</a>
    另外find()所选的css选择器选择的是所有的子孙节点,如果我们只想找子节点那么可以使用 children() 方法来查找,使用方法和find()方法是一样的,对pyquery对象传入css选择句就可以得到我们想要的结果了.

    • 父节点
      我们可以使用parent()的方法来获取某个节点的父节点,我们可以给其传入css查询语句来进行特定的查询.使用方法和children()方法一样,这里是该节点的直接父节点,不会再去查找该节点的祖先节点
    • 祖先节点
      和父节点一样,我们使用parents()来实现祖先借点的查找,同样的我们可以往里面传入css选择器参数查找我们需要的祖先节点
    • 兄弟节点
      使用siblings()方法来获取兄弟节点,同样的我们可以给它传入css选择参数来获取我们需要的节点
      遍历
      我们查到的对象不是想bs4那样返回一个列表,对于单个节点来说我们可以直接转成字符串使用
      str(doc('.li'))* 方法即可,对于多个节点,我们就需要使用遍历来获取内容了---.items() 方法
      对于我们选择的多个内容我们可以:
    doc = pq('html')
    list_cont = doc('li').items()  # 这里会得到一个生成器
    for i in list_cont:
        print(i)
    

    获取信息

    • 获取属性
      直接调用.attr() 方法可以获取属性

    doc.attr('href') # 类似这样的就可以获取他的herf属性了

    我们也可以直接调用.attr属性来获取属性,例如

    doc.attr.href

    这两种方法获取到的内容是一样的
    如果选中的是多个元素,我们调用attr()方法的时候就只会得到第一个节点的属性,这点可以自己去验证一下.当我们遇到这样的情况的时候就要使用遍历了也就是前面说的使用.items()来进行遍历操作.

    • 获取文本
      调用.text()方法可以获取选中节点里的所有文本的内容,它会忽略掉节点内部包含的所有HTML,值返回纯文字.
      但是如果想获取节点内部的HTML文本就要使用html()方法了.
      对于 html()方法返回的是第一个节点内部的HTML文本,而text()则返回了所有的节点内部的纯文本. 中间用一个空格隔开,也就是说结果返回的是一个字符串
      这个地方需要注意的是,如果结果是多个节点,并且想要获取每个节点内部的HTMl文本呢,那么就需要遍历每个节点,或者是使用text()方法来直接组合成一个字符串来获取.
      节点操作
    • addClass 和 removeClass 对class属性进行增减,具体是选中节点pyquery对象,然后进行修改

    doc.removeClass('example') # 我们给这个节点移除了example类属性

    doc.addClass('example') # 这里我们给这个节点增加了exmaple属性.

    • addr text 和 html
      我们可以使用一下形式直接更改节点里面的内容:
    html = '''
    <ul class="list">
    <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
    </ul>
    '''
    from pyquery import PyQuery as pq
    doc = pq(html)
    li = doc('.item-0.active')
    print(li)
    li.attr('name','link')  # 这里可以直接给节点添加一个属性
    print(li)
    li.text('change the world')  # 这里直接更改了节点的内容
    print(li)
    li.html("<span>change item</span>") # 这里修改了节点了的HTML内容
    print(li)
    

    输出结果如下:

    <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
    <li class="item-0 active" name="link"><a href="link3.html"><span class="bold">third item</span></a></li>
    <li class="item-0 active" name="link">change the world</li>
    <li class="item-0 active" name="link"><span>change item</span></li>

    在我们调用了attr()方法之后,li节点多了一个name属性,值为link,然后使用text方法传入文本改变了内部的文本信息,最后调用了html()方法来改变了节点的html的值
    所以,如果attr()方法只传入一个参数那么就是获取这个节点的属性值,如果传入第二个参数那么是可以修改这个参数的值的. 对于text()和html()方法,如果不传入参数就是获取内部的纯文本信息和HTML文本,如果传入参数就进行赋值修改

    • remove
      可以直接操作节点进行移除操作

    伪类选择器

    伪类选择器功能很强大具体参看w3School来查看更多的详情,这里我直接搬运过来了.

    一个普通标题 一个普通标题 一个普通标题
    选择器 例子 例子描述 CSS
    .class .intro 选择 class="intro" 的所有元素。 1
    #id #firstname 选择 id="firstname" 的所有元素。 1
    * * 选择所有元素。 2
    element p 选择所有 <p> 元素。 1
    element,element div,p 选择所有 <div> 元素和所有 <p> 元素。 1
    element element div p 选择 <div> 元素内部的所有 <p> 元素。 1
    element>element div>p 选择父元素为 <div> 元素的所有 <p> 元素。 2
    element+element div+p 选择紧接在 <div> 元素之后的所有 <p> 元素。 2
    [attribute] [target] 选择带有 target 属性所有元素。 2
    [attribute=value] [target=_blank] 选择 target="_blank" 的所有元素。 2
    [attribute~=value] [title~=flower] 选择 title 属性包含单词 "flower" 的所有元素。 2
    :link a:link 选择所有未被访问的链接。 1
    :visited a:visited 选择所有已被访问的链接。 1
    :active a:active 选择活动链接。 1
    :hover a:hover 选择鼠标指针位于其上的链接。 1
    :focus input:focus 选择获得焦点的 input 元素。 2
    :first-letter p:first-letter 选择每个 <p> 元素的首字母。 1
    :first-line p:first-line 选择每个 <p> 元素的首行。 1
    :first-child p:first-child 选择属于父元素的第一个子元素的每个 <p> 元素。 2
    :before p:before 在每个 <p> 元素的内容之前插入内容。 2
    :after p:after 在每个 <p> 元素的内容之后插入内容。 2
    :lang(language) p:lang(it) 选择带有以 "it" 开头的 lang 属性值的每个 <p> 元素。 2
    element1~element2 p~ul 选择前面有 <p> 元素的每个 <ul> 元素。 3
    [attribute^=value] a[src^="https"] 选择其 src 属性值以 "https" 开头的每个 <a> 元素。 3
    [attribute=value*] a[src*="abc"] 选择其 src 属性中包含 "abc" 子串的每个 <a> 元素。 3
    :first-of-type p:first-of-type 选择属于其父元素的首个 <p> 元素的每个 <p> 元素。 3
    :last-of-type p:last-of-type 选择属于其父元素的最后 <p> 元素的每个 <p> 元素。 3
    :only-of-type p:only-of-type 选择属于其父元素唯一的 <p> 元素的每个 <p> 元素。 3
    :only-child p:only-child 选择属于其父元素的唯一子元素的每个 <p> 元素。 3
    :nth-child(n) p:nth-child(2) 选择属于其父元素的第二个子元素的每个 <p> 元素。 3
    :nth-last-child(n) p:nth-last-child(2) 同上,从最后一个子元素开始计数。 3
    :nth-of-type(n) p:nth-of-type(2) 选择属于其父元素第二个 <p> 元素的每个 <p> 元素。 3
    :nth-last-of-type(n) p:nth-last-of-type(2) 同上,但是从最后一个子元素开始计数。 3
    :last-child p:last-child 选择属于其父元素最后一个子元素每个 <p> 元素。 3
    :root :root 选择文档的根元素。 3
    :empty p:empty 选择没有子元素的每个 <p> 元素(包括文本节点)。 3
    :target #news:target 选择当前活动的 #news 元素。 3
    :enabled input:enabled 选择每个启用的 <input> 元素。 3
    :disabled input:disabled 选择每个禁用的 <input> 元素 3
    :checked input:checked 选择每个被选中的 <input> 元素。 3
    :not(selector) :not(p) 选择非 <p> 元素的每个元素。 3
    ::selection ::selection 选择被用户选取的元素部分。 3

    到这里就结束了,这里只是简单的介绍,更详细的需要查看官方文档,下一篇我们来做一个简单的爬取淘宝商品的小项目.

    相关文章

      网友评论

        本文标题:爬虫解析库--pyquery以及css选择器的使用

        本文链接:https://www.haomeiwen.com/subject/rlehwftx.html