美文网首页python复习100天
python复习第16天:网页解析器之xpath

python复习第16天:网页解析器之xpath

作者: 潮办公 | 来源:发表于2020-04-06 23:24 被阅读0次

    title: python复习第16天:网页解析器之xpath
    date: 2020-04-06 23:00:24
    tags:
    - python
    - 爬虫
    categories: python复习
    top: 17


    Xpath 开发工具

    • 开源表达式编辑工具:XMLQuire

    • Chorme插件:Xpath Helper

    • 可以使用谷歌浏览器直接粘贴xpath路径,但是可能通用性不强

    使用方法

    1. 安装lxml
    pip install lxml
    conda install lxml
    
    1. 导入etree
    from lxml import etree
    
    1. 构建html树
    from lxml import etree
    
    text = """
    <!DOCTYPE html>
    <html lang="zh">
        <head>
            <meta charset="UTF-8">
            <title>这是标题</title>
        </head>
        <body>
        <div style="color:#FF0000"><p>这是段落1</p> </div>
        <div style="color:#FFFF00"><p>这是段落2</p> </div>
        <div style="color:#000000"><p>这是段落2</p> </div>
        </body>
    </html>
    """
    html = etree.HTML(text)
    

    选取节点

    • nodename:选取此节点的所有节点

    • /:根节点或者下一节点

    result = html.xpath('/html')
    print(result)
    """
    [<Element html at 0x7f2448926b40>]
    """
    
    • // :选取节点,不考虑位置
    result = html.xpath('//div')
    print(result)
    """
    [<Element div at 0x7f6de30e7960>, <Element div at 0x7f6de30e7910>, <Element div at 0x7f6de30e78c0>]
    """
    
    • . :选取当前节点
    result = html.xpath('//div')
    for r in result:
        s = r.xpath('./p')  # 选取当前div节点下的p节点
        print(s)
    """
    [<Element p at 0x7fd70835c780>]
    [<Element p at 0x7fd70835c730>]
    [<Element p at 0x7fd70835c780>]
    """
    
    • .. :选取当前节点的父节点
    result = html.xpath('//div')  # 选取div节点
    for r in result:
        s = r.xpath('..')  # 选取当前节点的父节点,div的父节点是body
        print(s)
    """
    [<Element body at 0x7f5d65f6f820>]
    [<Element body at 0x7f5d65f6f820>]
    [<Element body at 0x7f5d65f6f820>]
    """
    
    • @:选取属性
    result = html.xpath('//div[@style="color:#FF0000"]')  # 选取div节点,其中style = "color:#FF0000"
    print(result)
    """
    [<Element div at 0x7f6673d7b9b0>]
    """
    
    • / :一般安装路径查找,表示它的子节点
    • // :表示它的后代,包括子、孙

    提取属性或者文本

    • text():提取当前节点的文本
    result = html.xpath('//div/p/text()')  # 选取//div/p下的文本
    print(result)
    """
    ['这是段落1', '这是段落2', '这是段落2']
    """
    
    • string(.):提取当前节点以及子孙节点的所有文本
    result = html.xpath('string(.)')
    print(result)
    """
    
        
            
            这是标题
        
        
        这是段落1 
        这是段落2 
        这是段落2 
        
    
    
    """
    
    • @:提取某个属性,以提取百度官网的所有url为例
    import requests
    from lxml import etree
    from pprint import pprint
    import re
    url = 'https://www.baidu.com'
    headers = {
        'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko)\
         Chrome/80.0.3987.149 Safari/537.36'
    }
    response = requests.get(url, headers=headers)
    text = response.text
    html = etree.HTML(text)
    result = html.xpath('//a/@href')  # 选取所有a节点下的链接
    p = re.compile('http.?://.*?')  # 编写正则表达式,提取http或者https开头的网页
    list2 = []
    for r in result:
        result2 = p.match(r)  # 检测是否匹配
        if result2:  # 如果匹配
            list2.append(r)
    pprint(list2)
    """
    ['https://passport.baidu.com/v2/?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2F&sms=5',
     'https://voice.baidu.com/act/newpneumonia/newpneumonia/?from=osari_pc_1',
     'http://news.baidu.com',
     'https://www.hao123.com',
     'http://map.baidu.com',
     'http://v.baidu.com',
     'http://tieba.baidu.com',
     'http://xueshu.baidu.com',
     'https://passport.baidu.com/v2/?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2F&sms=5',
     'http://www.baidu.com/gaoji/preferences.html',
     'http://www.baidu.com/more/',
     'http://ir.baidu.com',
     'http://e.baidu.com/?refer=888',
     'http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=11000002000001',
     'http://tieba.baidu.com/f?kw=&fr=wwwt',
     'http://zhidao.baidu.com/q?ct=17&pn=0&tn=ikaslist&rn=10&word=&fr=wwwt',
     'http://music.taihe.com/search?fr=ps&ie=utf-8&key=',
     'http://image.baidu.com/search/index?tn=baiduimage&ps=1&ct=201326592&lm=-1&cl=2&nc=1&ie=utf-8&word=',
     'http://v.baidu.com/v?ct=301989888&rn=20&pn=0&db=0&s=25&ie=utf-8&word=',
     'http://map.baidu.com/m?word=&fr=ps01000',
     'http://wenku.baidu.com/search?word=&lm=0&od=0&ie=utf-8']
    """
    

    谓语-Predicates

    • /School/Student[1] :选取School下面第一个节点
    • /School/Student[last()] : 选取School下面最后一个节点
    • /School/Student[position()<3] : 选取School下面前三个节点
    • //Student[@score="99"] 选取属性带有99的节点

    Xpath运算符

    运算符 描述 实例 返回值
    | 计算两个节点集 //book | //cd 返回所有拥有 book 和 cd 元素的节点集
    + 加法 6 + 4 10
    - 减法 6 - 4 2
    * 乘法 6 * 4 24
    div 除法 8 div 4 2
    = 等于 price=9.80 如果 price 是 9.80,则返回 true。如果 price 是 9.90,则返回 false。
    != 不等于 price!=9.80 如果 price 是 9.90,则返回 true。如果 price 是 9.80,则返回 false。
    < 小于 price<9.80 如果 price 是 9.00,则返回 true。如果 price 是 9.90,则返回 false。
    <= 小于或等于 price<=9.80 如果 price 是 9.00,则返回 true。如果 price 是 9.90,则返回 false。
    > 大于 price>9.80 如果 price 是 9.90,则返回 true。如果 price 是 9.80,则返回 false。
    >= 大于或等于 price>=9.80 如果 price 是 9.90,则返回 true。如果 price 是 9.70,则返回 false。
    or price=9.80 or price=9.70 如果 price 是 9.80,则返回 true。如果 price 是 9.50,则返回 false。
    and price>9.00 and price<9.90 如果 price 是 9.80,则返回 true。如果 price 是 8.50,则返回 false。
    mod 计算除法的余数 5 mod 2 1

    相关文章

      网友评论

        本文标题:python复习第16天:网页解析器之xpath

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