zoukankan      html  css  js  c++  java
  • 7,pyquery获取数据

    https://pyquery.readthedocs.io/en/latest/

    pyquery allows you to make jquery queries on xml documents. The API is as much as possible the similar to jquery. pyquery uses lxml for fast xml and html manipulation.

    pyquery库是jQuery的Python实现,能够以jQuery的语法来操作解析 HTML 文档
    pyquery uses lxml for fast xml and html manipulation

    参考网站

    https://pyquery.readthedocs.io/en/latest/
    https://www.jianshu.com/p/770c0cdef481
    https://pythonhosted.org/pyquery/css.html
    https://www.osgeo.cn/pyquery/index.html

    https://pyquery.readthedocs.io/en/latest/api.html

    初始化对象

    ##############字符串初始化
    from pyquery import PyQuery as pq
    #初始化为PyQuery对象
    doc = pq(html)
    print(type(doc))
    print(doc)
    
    
    
    ####html 文件初始化
    #filename参数为html文件路径
    test_html = pq(filename = 'test.html')
    print(type(test_html))
    print(test_html)
    
    ####网址获取
    response = pq(url = 'https://www.baidu.com')
    print(type(response))
    print(response)
    
    ###官方初始化
    >>> from pyquery import PyQuery as pq
    >>> from lxml import etree
    >>> import urllib
    >>> d = pq("<html></html>")
    >>> d = pq(etree.fromstring("<html></html>"))
    >>> d = pq(url=your_url)
    >>> d = pq(url=your_url,
    ...        opener=lambda url, **kw: urlopen(url).read())
    >>> d = pq(filename=path_to_html_file)
    

    获取元素

    根据html 标签获取元素

    from pyquery import PyQuery
    
    html = '''
    <div>
        <p>test 1</p>
        <p>test 2</p>
    </div>
    '''
    p = PyQuery(html)
    
    # 获取所有p标签
    p('p')   #这种方式获取的结果对象为  <class 'pyquery.pyquery.PyQuery'>
    >>> [<p>, <p>]
    
    print(p('p'))
    >>> <p>test 1</p>
        <p>test 2</p>
    
    p.find('p')  #获取的结果为<class 'lxml.html.HtmlElement'>
    
    

    eq 根据给定的索引号得到指定元素

    # 获取第一个p标签的内容
    p('p').eq(0).html()
    >>> 'test 1'
    
    # 获取第二个p标签的内容
    p('p').eq(1).html()
    >>> 'test 2'
    
    # 不用 eq 方法默认返回第一个
    p('p').html()
    >>> 'test 1'
    

    类名id获取元素

    from pyquery import PyQuery as pq
     
    html = '''<div>
        <ul id = 'haha'>
             <li class="item-0">first item</li>
             <li class="item-1"><a href="link2.html">second item</a></li>
             <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
             <li class="item-1 active"><a href="link4.html">fourth item</a></li>
             <li class="item-0"><a href="link5.html">fifth item</a></li>
         </ul></div>'''
     
    doc = pq(html)
    print(doc)
    #id等于haha下面的class等于item-0下的a标签下的span标签(注意层级关系以空格隔开)
    print(doc('#haha .item-0 a span'))
    
    #####
    # 根据id名获取元素
    p('#1').html()   
    >>> 'test 1'
    
    # 根据class名获取元素
    >>> p('.abc').html()
    'test 2'
    

    html 函数

    获取相应的 HTML 块

    text():获取文本块

    from pyquery import PyQuery as pq
    
    
    html = '''<div>
        <ul id = 'haha'>
             <li class="item-0">first item</li>
             <li class="item-1"><a href="link2.html">second item</a></li>
             <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
             <li class="item-1 active"><a href="link4.html">fourth item</a></li>
             <li class="item-0"><a href="link5.html">fifth item</a></li>
         </ul></div>'''
    
    doc = pq(html)
    print(doc)
    # id等于haha下面的class等于item-0下的a标签下的span标签(注意层级关系以空格隔开)
    # print(doc('#haha .item-0 a span'))
    print("
    ")
    print(doc.html())
    
    print("text")
    print(doc.text())
    
    
    ###结果
    <div>
        <ul id="haha">
             <li class="item-0">first item</li>
             <li class="item-1"><a href="link2.html">second item</a></li>
             <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
             <li class="item-1 active"><a href="link4.html">fourth item</a></li>
             <li class="item-0"><a href="link5.html">fifth item</a></li>
         </ul></div>
    
    
    
        <ul id="haha">
             <li class="item-0">first item</li>
             <li class="item-1"><a href="link2.html">second item</a></li>
             <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
             <li class="item-1 active"><a href="link4.html">fourth item</a></li>
             <li class="item-0"><a href="link5.html">fifth item</a></li>
         </ul>
    doc.text() 函数
    first item
    second item
    third item
    fourth item
    fifth item
    
    

    获取属性值

    html = '''
    <p id='my_id'>
        <a href='http://hello.com'>hello</a>
    </p>
    '''
    p('a').attr('href') 
    
    ####
    html = '''
    <p id='my_id'>
        <a href='http://hello.com'>hello</a>
    </p>
    '''
    >>doc = pq(html)
    >>doc('a').attr('href') ##print(item.attr.href)
    'http://hello.com'
    >>doc('a')
    [<a>]
    >>doc('a')[0].values()
    ['http://hello.com']
    >>a = doc('a')[0]
    >>a.get("href")
    'http://hello.com'
    
    
    
    

    获取子元素

    from pyquery import PyQuery
    
    html = '''
    <span>
        <p id='1'>hello</p>
        <p id='2'>world</p>
    </span>
    '''
    p = PyQuery(html)
    
    # 提取div的所有子元素
    p.children()
    >>> [<p#1>, <p#2>]
    
    # 提取div下id=‘1’的子元素
    p.children('#1')
    >>> [<p#1>]
    

    父元素

    #######################分离_________________________________________________

    常用的CCS选择器

    打印id为container的标签

    print(doc('#container'))
    print(type(doc('#container')))
    

    打印class为object-1的标签

    print(doc('.object-1'))
    

    打印标签名为body的标签

    print(doc('body'))
    

    多种css选择器使用

    print(doc('html #container'))
    

    伪类选择器

    print(pseudo_doc('li:nth-child(2)'))
    
    #打印第一个li标签
    print(pseudo_doc('li:first-child'))
    
    #打印最后一个标签
    print(pseudo_doc('li:last-child'))
    

    contains

    #找到含有Python的li标签
    print(pseudo_doc("li:contains('Python')"))
    
    #找到含有好的li标签
    print(pseudo_doc("li:contains('好')"))
    

    查找标签

    按照条件在Pyquery对象中查找符合条件的标签,类似于BeautifulSoup中的find方法。

    打印id=container的标签

    print(doc.find('#container'))
    print(doc.find('li'))
    

    子辈标签-children方法

    #id=container的标签的子辈标签
    container = doc.find('#container')
    print(container.children())
    

    父辈标签-parent方法

    object_2 = doc.find('.object-2')
    print(object_2.parent())
    

    兄弟标签-siblings方法

    object_2 = doc.find('.object-2')
    print(object_2.siblings())
    

    获取标签的信息

    定位到目标标签后,我们需要标签内部的文本或者属性值,这时候需要进行提取文本或属性值操作

    标签属性值的提取

    .attr() 传入 标签的属性名,返回属性值

    object_2 = doc.find('.object-2')
    print(object_2.attr('class'))
    
    标签内的文本
    html_text = """
    <html lang="en">
        <head>
            简单好用的
            <title>PyQuery</title>
        </head>
        <body>
            <ul id="container">
                Hello World!
                <li class="object-1">Python</li>
                <li class="object-2">大法</li>
                <li class="object-3">好</li>
            </ul>
        </body>
    </html>
    """
    
    docs = pq(html_text)
    print(docs.text())
    
    ######
    object_1 = docs.find('.object-1')
    print(object_1.text())
    container = docs.find('#container')
    print(container.text())
    
    
    tips:如果我只想获得Hello World这个,不想得到其他的文本,可以使用remove方法将li标签去掉,然后再使用text方法
    container = docs.find('#container')
    container.remove('li')
    print(container.text())
    

    pyquery一些自定义的用法

    PyQuery与BeautifulSoup对比,我们会发现PyQuery可以对网址发起请求

    from pyquery import PyQuery
    PyQuery(url = 'https://www.baidu.com')
    

    opener参数

    这是PyQuery对百度网址进行请求,并将请求返回的响应数据处理为PyQuery对象。一般pyquery库会默认调用urllib库,如果想使用selenium或者requests库,可以自定义PyQuery的opener参数。

    opener参数作用是告诉pyquery用什么请求库对网址发起请求。常见的请求库如urllib、requests、selenium。这里我们自定义一个selenium的opener。

    from pyquery import PyQuery
    from selenium.webdriver import PhantomJS
    
    #用selenium访问url
    def selenium_opener(url):
        #我没有将Phantomjs放到环境变量,所以每次用都要放上路径
        driver = PhantomJS(executable_path = 'phantomjs的路径')
        driver.get(url)
        html = driver.page_source
        driver.quit()
        return html
    
    #注意,使用时opener参数是函数名,没有括号的!
    PyQuery(url='https://www.baidu.com/', opener=selenium_opener)
    

    cookies、headers

    在requests用法中,一般为了访问网址更加真实,模仿成浏览器。一般我们需要传入headers,必要的时候还需要传入cookies参数。而pyquery库就有这功能,也能伪装浏览器。

    from pyquery import PyQuery
    
    cookies = {'Cookie':'你的cookie'}
    headers = {'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'}
    
    
    PyQuery(url='https://www.baidu.com/',headers=headers,cookies=cookies)
    

    让你的selenium带上pyquery功能

    from pyquery import PyQuery
    from selenium.webdriver import PhantomJS
    
    class Browser(PhantomJS):
        @property    
        def dom(self):
            return PyQuery(self.page_source)"""
    这部分property是装饰器,需要知道@property下面紧跟的函数,实现了类的属性功能。
    这里browser.dom,就是browser的dom属性。
    """
    
    browser = Browser(executable_path='phantomjs的路径')
    browser.get(url='https://www.baidu.com/')
    print(type(browser.dom))
    

    PyQuery-获取数据

    api文档

    初始化

    初始化的时候一般有三种传入方式:传入字符串,传入url,传入文件

    字符串初始化

    html = '''
    <div>
        <ul>
             <li class="item-0">first item</li>
             <li class="item-1"><a href="link2.html">second item</a></li>
             <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
             <li class="item-1 active"><a href="link4.html">fourth item</a></li>
             <li class="item-0"><a href="link5.html">fifth item</a></li>
         </ul>
    </div>
    '''
    
    from pyquery import PyQuery as pq
    doc = pq(html)
    print(doc)
    print(type(doc))
    print(doc('li'))
    
    # 代码中的doc其实就是一个pyquery对象,我们可以通过doc可以进行元素的选择,其实这里就是一个css选择器,所以CSS选择器的规则都可以用,直接doc(标签名)就可以获取所有的该标签的内容,如果想要获取class 则doc('.class_name'),如果是id则doc('#id_name')....
    
    

    URL初始化

    from pyquery import PyQuery as pq
    
    doc = pq(url="http://www.baidu.com",encoding='utf-8')
    print(doc('head'))
    

    文件初始化

    pq(filename='index.html')

    基本的CSS选择器

    html = '''
    <div id="container">
        <ul class="list">
             <li class="item-0">first item</li>
             <li class="item-1"><a href="link2.html">second item</a></li>
             <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
             <li class="item-1 active"><a href="link4.html">fourth item</a></li>
             <li class="item-0"><a href="link5.html">fifth item</a></li>
         </ul>
     </div>
    '''
    from pyquery import PyQuery as pq
    doc = pq(html)
    print(doc('#container .list li'))
    
    # doc('#container .list li'),这里的三者之间的并不是必须要挨着,只要是层级关系就可以
    

    常用的CSS选择器方法:

    .class    .color   选择class="color"的所有元素
    #id       .info    选择id="info"的所有元素
    *          *       选择所有元素
    element   p        选择所有的p元素
    element,element    div,p        选择所有的div元素和所有的p元素
    element element    div p        选择div标签内部所有的p元素
    [attribute]        [target]     选择带有target属性的元素
    [attribute=value]        [target=_blank]     选择target=_blank的所有元素
    
    

    查找元素

    子元素

    children,find

    
    html = '''
    <div id="container">
        <ul class="list">
             <li class="item-0">first item</li>
             <li class="item-1"><a href="link2.html">second item</a></li>
             <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
             <li class="item-1 active"><a href="link4.html">fourth item</a></li>
             <li class="item-0"><a href="link5.html">fifth item</a></li>
         </ul>
     </div>
    '''
    from pyquery import PyQuery as pq
    doc = pq(html)
    items = doc('.list')
    print(type(items))
    print(items)
    lis = items.find('li')
    print(type(lis))
    print(lis)
    
     # 通过pyquery找到结果其实还是一个pyquery对象,可以继续查找,上述中的代码中的items.find('li') 则表示查找ul里的所有的li标签
    

    通过children可以实现同样的效果,并且通过.children方法得到的结果也是一个pyquery对象

    li = items.children()
    print(type(li))
    print(li)
    
    # 同时在children里也可以用CSS选择器
    
    li2 = items.children('.active') print(li2)
    

    父元素

    parent,parents方法

    通过.parent就可以找到父元素的内容

    html = '''
    <div id="container">
        <ul class="list">
             <li class="item-0">first item</li>
             <li class="item-1"><a href="link2.html">second item</a></li>
             <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
             <li class="item-1 active"><a href="link4.html">fourth item</a></li>
             <li class="item-0"><a href="link5.html">fifth item</a></li>
         </ul>
     </div>
    '''
    from pyquery import PyQuery as pq
    doc = pq(html)
    items = doc('.list')
    container = items.parent()
    print(type(container))
    print(container)
    

    通过.parents就可以找到祖先节点的内容

    html = '''
    <div class="wrap">
        <div id="container">
            <ul class="list">
                 <li class="item-0">first item</li>
                 <li class="item-1"><a href="link2.html">second item</a></li>
                 <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
                 <li class="item-1 active"><a href="link4.html">fourth item</a></li>
                 <li class="item-0"><a href="link5.html">fifth item</a></li>
             </ul>
         </div>
     </div>
    '''
    from pyquery import PyQuery as pq
    doc = pq(html)
    items = doc('.list')
    parents = items.parents()
    print(type(parents))
    print(parents)
    
    

    同样我们通过.parents查找的时候也可以添加css选择器来进行内容的筛选

    兄弟元素

    siblings

    html = '''
    <div class="wrap">
        <div id="container">
            <ul class="list">
                 <li class="item-0">first item</li>
                 <li class="item-1"><a href="link2.html">second item</a></li>
                 <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
                 <li class="item-1 active"><a href="link4.html">fourth item</a></li>
                 <li class="item-0"><a href="link5.html">fifth item</a></li>
             </ul>
         </div>
     </div>
    '''
    from pyquery import PyQuery as pq
    doc = pq(html)
    li = doc('.list .item-0.active')
    print(li.siblings())
    

    代码中doc('.list .item-0.active') 中的.tem-0和.active是紧挨着的,所以表示是并的关系,这样满足条件的就剩下一个了:thired item的那个标签了
    这样在通过.siblings就可以获取所有的兄弟标签,当然这里是不包括自己的
    同样的在.siblings()里也是可以通过CSS选择器进行筛选

    遍历

    单个元素

    html = '''
    <div class="wrap">
        <div id="container">
            <ul class="list">
                 <li class="item-0">first item</li>
                 <li class="item-1"><a href="link2.html">second item</a></li>
                 <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
                 <li class="item-1 active"><a href="link4.html">fourth item</a></li>
                 <li class="item-0"><a href="link5.html">fifth item</a></li>
             </ul>
         </div>
    </div>
    '''
    from pyquery import PyQuery as pq
    doc = pq(html)
    li = doc('.item-0.active')
    print(li)
    
    lis = doc('li').items()
    print(type(lis))
    for li in lis:
        print(type(li))
        print(li)
    ##通过items()可以得到一个生成器,并且我们通过for循环得到的每个元素依然是一个pyquery对象
    

    获取信息

    获取属性
    pyquery对象.attr(属性名)
    pyquery对象.attr.属性名

    html = '''
    <div class="wrap">
        <div id="container">
            <ul class="list">
                 <li class="item-0">first item</li>
                 <li class="item-1"><a href="link2.html">second item</a></li>
                 <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
                 <li class="item-1 active"><a href="link4.html">fourth item</a></li>
                 <li class="item-0"><a href="link5.html">fifth item</a></li>
             </ul>
         </div>
     </div>
    '''
    from pyquery import PyQuery as pq
    doc = pq(html)
    a = doc('.item-0.active a')
    print(a)
    print(a.attr('href'))
    print(a.attr.href)
    #获得属性值的时候可以直接a.attr(属性名)或者a.attr.属性名
    

    获取文本

    在很多时候我们是需要获取被html标签包含的文本信息,通过.text()就可以获取文本信息

    html = '''
    <div class="wrap">
        <div id="container">
            <ul class="list">
                 <li class="item-0">first item</li>
                 <li class="item-1"><a href="link2.html">second item</a></li>
                 <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
                 <li class="item-1 active"><a href="link4.html">fourth item</a></li>
                 <li class="item-0"><a href="link5.html">fifth item</a></li>
             </ul>
         </div>
     </div>
    '''
    from pyquery import PyQuery as pq
    doc = pq(html)
    a = doc('.item-0.active a')
    print(a)
    print(a.text())
    

    获取html

    我们通过.html()的方式可以获取当前标签所包含的html信息,

    html = '''
    <div class="wrap">
        <div id="container">
            <ul class="list">
                 <li class="item-0">first item</li>
                 <li class="item-1"><a href="link2.html">second item</a></li>
                 <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
                 <li class="item-1 active"><a href="link4.html">fourth item</a></li>
                 <li class="item-0"><a href="link5.html">fifth item</a></li>
             </ul>
         </div>
     </div>
    '''
    from pyquery import PyQuery as pq
    doc = pq(html)
    li = doc('.item-0.active')
    print(li)
    print(li.html())
    

    DOM操作

    addClass、removeClass
    熟悉前端操作的话,通过这两个操作可以添加和删除属性

    html = '''
    <div class="wrap">
        <div id="container">
            <ul class="list">
                 <li class="item-0">first item</li>
                 <li class="item-1"><a href="link2.html">second item</a></li>
                 <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
                 <li class="item-1 active"><a href="link4.html">fourth item</a></li>
                 <li class="item-0"><a href="link5.html">fifth item</a></li>
             </ul>
         </div>
     </div>
    '''
    from pyquery import PyQuery as pq
    doc = pq(html)
    li = doc('.item-0.active')
    print(li)
    li.removeClass('active')
    print(li)
    li.addClass('active')
    print(li)
    

    attr,css

    同样的我们可以通过attr给标签添加和修改属性,
    如果之前没有该属性则是添加,如果有则是修改
    我们也可以通过css添加一些css属性,这个时候,标签的属性里会多一个style属性

    html = '''
    <div class="wrap">
        <div id="container">
            <ul class="list">
                 <li class="item-0">first item</li>
                 <li class="item-1"><a href="link2.html">second item</a></li>
                 <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
                 <li class="item-1 active"><a href="link4.html">fourth item</a></li>
                 <li class="item-0"><a href="link5.html">fifth item</a></li>
             </ul>
         </div>
     </div>
    '''
    from pyquery import PyQuery as pq
    doc = pq(html)
    li = doc('.item-0.active')
    print(li)
    li.attr('name', 'link')
    print(li)
    li.css('font-size', '14px')
    print(li)
    

    remove

    有时候我们获取文本信息的时候可能并列的会有一些其他标签干扰,这个时候通过remove就可以将无用的或者干扰的标签直接删除,从而方便操作

    html = '''
    <div class="wrap">
        Hello, World
        <p>This is a paragraph.</p>
     </div>
    '''
    from pyquery import PyQuery as pq
    doc = pq(html)
    wrap = doc('.wrap')
    print(wrap.text())
    wrap.find('p').remove()
    print(wrap.text())
    
    
  • 相关阅读:
    微软开发中心的rss历史记录(22)
    asp.net dll 动态生成和调用(转)
    准备写博了
    来博客园报道啦
    web爬行器的准备工作
    跨浏览器设置标签样式
    感谢我身边的朋友们
    难过的一天:(
    12月:期待好运来
    11月 难过一整个世界都寂寞
  • 原文地址:https://www.cnblogs.com/g2thend/p/12452212.html
Copyright © 2011-2022 走看看