• XPath


    xpath(XML Path Language)是一门在XML和HTML文档中查找信息的语言,可以用来在XML和HTML文档中对元素和属性进行遍历。

    XPath开发工具

    1.Chrome插件XPath Helper。

    2.Firefox插件Try XPath。

    XPath 使用路径表达式来选取XMl文档中的节点或者节点集。

    表达式 描述 示例 结果
    nodename 选取此节点的所有子节点 bookstore 选取bookstore下所有的子节点
    /

    如果是在最前面,代表从根节点选取。

    否则,代表选择某节点下的某节点

    /bookstore 选取根节点下所有的bookstore节点
    // 从全局节点中选取节点,随便在哪个位置 //book 从全局节点中找到所有book节点
    @ 选取某个节点的属性 //book[@price] 选取所有含有price属性的book标签

    通过使用路径表达式中的‘|’运算符来选取多个路径:

    # 选取所有的book元素以及book元素下所有的title元素
    //bookstore/book|//book/title
    

      

    谓语:

    谓语用来查找某个特定的节点或者包含某个指定的值的节点,被嵌在 [] 中。常见的带有谓语的路径表达式及其结果如下所示:

    路径表达式 描述
    /bookstore/book[1] 选取bookstor下的第一个book元素
    /bookstore/book[last()] 选取bookstore下的最后一个book元素
    bookstore/book[position()<3] 选取bookstore下的前两个book元素
    //book[@price] 选取拥有price属性的book元素
    //book[@price=10] 选取所有price属性值为10的book元素

    [] 的下标从1开始。

    通配符:

    * 表示通配符。

    通配符 描述 示例 结果
    * 匹配任意节点 /bookstore/* 选取bookstore下的所有子元素
    @* 匹配节点中的任何属性 //book[@*] 选取所有带有属性的book元素

    XPath语法:

    使用方式:

    使用//获取整个页面的元素,然后写标签名,再然后写谓词金进行提取。比如:

    //div[@class='abc']
    

      需要注意:

    1. /  和 // 的区别:/代表只是获取直接子节点。// 获取子孙节点。一般 //用的比较多。

    2. contains: 有时某个属性包含多个值,那么可以使用‘contains’函数。

    //div[contains(@class,'job_detail')]
    

    3. 谓词中的下标是从1开始的。

      

    通过使用 lxml 库来使用XPath语法来解析网页数据。

    lxml 是一个HTML/XML的解析器,主要功能是解析和提取HTML和XML数据。lxml 和正则一样,也是用c实现的,是一款高性能的python HTML/XML 

    解析器。可以利用XPath语法来快速的定位特定元素以及节点信息。

    lxml python官方文档:http://lxml.de/index.html

    使用 pip 安装: pip install lxml

    使用 lxml 解析HTML代码:

    1. 解析 html 字符串(text 是HTML格式的字符串):使用' lxml.etree.HTML'进行解析。示例代码:

    htmlElement = etree.HTML(text)
    print(etree.tostring(htmlElement,encoding='utf-8').decode('utf-8'))
    

    2. 解析html文件:使用'lxml.etree.parse'进行解析。示例代码:

    htmlElement = etree.parse('tencent.html')
    print(etree.tostring(htmlElement,encoding='utf-8').decode('utf-8'))
    

     'etree.parse' 使用的是‘XML’解析器,所以如果碰到一些不规范的‘HTML’代码时就会解析错误,这时就要自己创建‘HTML’解析器。

    # etree.HTMLParser 创建一个‘HTML’解析器
    parser = etree.HTMLParser(encoding='utf-8')
    htmlElement = etree.parse('tencent.html',parser=parser)
    print(etree.tostring(htmlElement,encoding='utf-8').decode('utf-8'))
    

     

    from lxml import etree
    
    """
    1. 获取所有的tr标签
    2.获取第二个tr标签
    3. 获取所有的class等于even的标签
    4. 获取所有a标签的href属性值
    5,获取所有的职位信息(纯文本)
    """
    
    parser = etree.HTMLParser(encoding='utf-8')
    html = etree.parse("tencent.html",parser=parser)
    
    # 1. 获取所有tr标签
    # xpath函数返回的是一个列表
    trs = html.xpath('//tr')
    for tr in trs:
        print(etree.tostring(tr,encoding='utf-8').decode('utf-8'))
    
    # 2. 获取第二个tr标签
    secondtr = html.xpath('//tr(2)')[0]
    
    # 3. 获取所有的class等于even的标签
    trs = html.xpath("//tr[@class="even"]")
    for tr in trs:
        print(etree.tostring(tr,encoding='utf-8').deconde('utf-8'))
    
    
    # 4. 获取所有a标签的href属性值
    """
    获取所有a标签的href属性的值[‘’//a/@href’’]; 
    获取所有含有href 属性的 a标签//a[@href]。
    """
    alist = html.xpath("//a/@href")
    for a in alist:
        print('http://hr.tencent.com/'+a)
    
    
    # 5. 获取获取所有的职位信息(纯文本)
    trs = html.xpath("//tr[position()>1]")
    positions = []
    for tr in trs:
        href = tr.xpath(".//a/@href")[0]
        fullurl = 'http://hr.tencent.com/'+href
        title = tr.xpath("./td[1]//text()")[0]
        category = tr.xpath("./td[2]//text()")[0]
        nums = tr.xpath("./td[3]//text()")[0]
        address = tr.xpath("./td[4]/text()")[0]
        pubtime = tr.xpath('./td[5]/text()')[0]
        
        
        position = {
            'url':fullurl,
            'title':title,
            'category':category,
            'address':address,
            'pubtime':pubtime
        }
        positions.append(position)
    View Code

    lxml 结合 xpath注意事项:

    1. 使用‘xpath’语法应该使用'Element.xpath'方法来执行xpath的选择。示例代码:

    trs = html.xpath("//tr[positon()>1]")
    

      'xpath'函数返回的是一个列表。

    2, 获取某个标签的属性:

    href = html.xpath("//a/@href")
    

    3. 通过'xpath'中的‘text()’ 函数获取文本。

    address = tr.xpath("./td[4]/text()")[0]
    

      

     4. 在某个标签下,再执行xpath函数,获取这个标签下的子孙元素,那么应该在‘/’之前加一个点,代表是在当前元素下获取。

     

    import requests
    from lxml import etree
    
    
    
    
    
    # 1. 将目标页面的数据抓取下来
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3642.0 Safari/537.36',
        'Referer':'https://movie.douban.com/'
    
    }
    
    
    url = 'https://movie.douban.com/cinema/nowplaying/xuchang/'
    response = requests.get(url,headers=headers)
    text = response.text
    
    # 2. 根据一定的规则对抓取下来的数据进行提取 
    html = etree.HTML(text)
    
    # 正在上映的电影的标签,  [1]即将上映的电影的标签
    ul = html.xpath("//ul[@class='lists']")[0]
    # # 查看获取的ul标签
    # print(etree.tostring(ul,encoding='utf-8').decode('utf-8'))
    
    # 获取li标签
    lis = ul.xpath("./li")
    movies = []
    for li in lis:
        title = li.xpath('@data-title')[0]
        score = li.xpath('@data-score')[0]
        duration = li.xpath('@data-duration')[0]
        region = li.xpath('@data-region')[0]
        direcrot = li.xpath('@data-director')[0]
        actors = li.xpath('@data-actors')[0]
        thumbnail = li.xpath(".//img/@src")[0]
        movie = {
            'title':title,
            'score':score,
            'duration':duration,
            'region': region,
            'direcrot':direcrot,
            'actors':actors,
            'thumbnail':thumbnail
    
        }
        movies.append(movie)
    
    print(movies)
    View Code
    import requests
    from lxml import etree
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3642.0 Safari/537.36'
    }
    BASE_DOMAIN = 'https://www.dytt8.net'
    def get_detail_urls(url):
        response = requests.get(url, headers=headers)
        text = response.text
        html = etree.HTML(text)
        detail_urls = html.xpath("//table[@class='tbspan']//a/@href")
        # detail_urls = []
        # for get_detail_url in detail_urls:
        #     detail_url = BASE_DOMAIN + get_detail_url
        #     detail_urls.append(detail_url)
    
        detail_urls = map(lambda url:BASE_DOMAIN+url,detail_urls)
        return detail_urls
    
    def parse_detail_page(url):
        movie = {}
        response = requests.get(url,headers=headers)
        text = response.content.decode('gbk')
    
        html = etree.HTML(text)
        title = html.xpath("//div[@class='title_all']//font[@color='#07519a']/text()")[0]
        movie['title'] = title
        zooms = html.xpath("//div[@id='Zoom']")[0]
        imgs = zooms.xpath(".//img/@src")
        # 封面图
        coverimg = imgs[0]
      
    
        movie['cover'] = coverimg
      
    
        def pares_info(info,rule):
            return info.replace(rule,'').strip()
    
        infos = zooms.xpath(".//text()")
        for index,info in enumerate(infos):
            if info.startswith("◎年  代"):
                # info = info.replace("◎年  代",'').strip()
                info = pares_info(info,"◎年  代")
                movie['year'] = info
            elif info.startswith("◎产  地"):
                info = pares_info(info, "◎产  地")
                movie['country'] = info
            elif info.startswith("◎类  别"):
                info = pares_info(info, "◎类  别")
                movie['category'] = info
            elif info.startswith("◎豆瓣评分"):
                info = pares_info(info, "◎豆瓣评分")
                movie['douban_rating'] = info
            elif info.startswith("◎片  长"):
                info = pares_info(info, "◎片  长")
                movie['duration'] = info
            elif info.startswith("◎导  演"):
                info = pares_info(info, "◎导  演")
                movie['director'] = info
            elif info.startswith("◎主  演"):
                info = pares_info(info, "◎主  演")
                actors = [info]
                for x in range(index+1,len(infos)):
                    # 去除空白字符
                    actor = infos[x].strip()
                    if actor.startswith(""):
                        break
                    actors.append(actor)
                movie['actors'] = actors
            elif info.startswith("◎简  介"):
                info = pares_info(info, "◎简  介")
                for x in range(index + 1, len(infos)):
                    profile = infos[x].strip()
                    movie['profile'] = profile
        download_url = html.xpath("//td[@bgcolor='#fdfddf']/a/@href")[0]
        movie['download_url'] = download_url
        return movie
    
    
    
        pass
    
    def spider():
        base_url = 'https://www.dytt8.net/html/gndy/dyzz/list_23_{}.html'
        # 页数
        movies = []
        for x in range(1,223):
            url = base_url.format(x)
            detail_urls = get_detail_urls(url)
            # 一页中的所有详情的URL
            for detail_url in detail_urls:
                movie = parse_detail_page(detail_url)
                movies.append(movie)
                print(movie)
    
        # print(movies)
    
    
    
    
    if __name__ =='__main__':
        spider()
    View Code
  • 相关阅读:
    模拟实现ajax加载框
    京东晒单的js实现
    微信分享js代码(转载)
    css模拟实现selec下拉框
    网页端实现输入卡号四字隔开
    返回顶部的动态显示与隐藏
    js等比例缩放图片(转载)
    css模拟实现checkbox
    quartz的使用 Mr
    Spring声明式事务配置管理方法 Mr
  • 原文地址:https://www.cnblogs.com/-hao-/p/13842995.html
Copyright © 2020-2023  润新知