zoukankan      html  css  js  c++  java
  • python--爬虫(XPath与BeautifulSoup4)

    获取页面内容除使用正则意外,还可以使用XPath,其原理是将html代码转换为xml格式,然后使用XPath查找html节点或元素。

    选取节点

    XPath使用路径表达式来选取XML文档中的节点或节点集。
    常用的路径表达式见下表:

    表达式 描述
    nodename 选取此节点的所有子节点
    / 从根节点选取
    // 从匹配选择的当前节点选择文档中的节点,不考虑其是否为子级
    . 选取当前节点
    .. 选取当前节点的父节点
    @ 选取属性

    谓语

    谓语用来查找某个特定的节点或者包含某个指定的值得节点,被嵌在方括号中。

    路径表达式 释义
    /one/two[1] 选取属于one子元素的第一个two元素
    /one/two[last()] 选取属于one子元素的最后一个two元素
    /one/two[last()-1] 选取属于one子元素的倒数第二个two元素
    /one/two[position()❤️] 选取最前面的两个属于one元素的子元素two元素
    //one[@lang] 选取所有拥有名为lang的属性的one元素
    //one[@lang='test'] 选取所有拥有值为test的lang属性的one元素
    /one/two[position>10] 选取one元素的所有two元素,且其中position属性的值大于10

    选取未知节点

    通配符 描述
    * 匹配如何元素节点
    @* 匹配任何属性节点
    node() 匹配任何类型节点

    例:

    路径表达式 结果
    /one/* 选取one中所有的子元素
    //* 选取文档中的所有元素
    //one[@*] 选取所有带有属性的one元素

    选取若干路径

    可以使用管道符“|”选取若干个路径,相当于或

    XPath运算符

    运算符 描述
    + 加法
    - 减法
    * 乘法
    div 除法
    = 等于
    != 不等于
    < 小于
    <= 小于或等于
    > 大于
    >= 大于或等于
    or
    and
    mod 计算余数

    XPath的使用

    from lxml.html import etree
    
    # 获取到的要匹配的html字符串
    html = ''
    content = etree.HTML(html)
    # 返回所有匹配成功的列表集合
    res = content.xpath('表达式')
    

    BeautifulSoup4的使用

    和 lxml 一样,Beautiful Soup 也是一个HTML/XML的解析器,主要的功能也是如何解析和提取 HTML/XML 数据。
    想使用BeautifulSoup4首先需要安装,执行pip install beautifulsoup4安装,BeautifulSoup4的使用方法如下

    from bs4 import BeautifulSoup
    
    html = """
    <html><head><title>The Dormouse's story</title></head>
    <body>
    <p class="title" name="dromouse"><b>The Dormouse's story</b></p>
    <p class="story">Once upon a time there were three little sisters; and their names were
    <a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
    <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
    <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
    and they lived at the bottom of a well.</p>
    <p class="story">...</p>
    """
    soup = BeautifulSoup(html, 'lxml')
    # 打开本地Html文件创建对象
    # soup = BeautifulSoup(open('xxx.html'))
    
    print(soup.prettify())
    
    # 获取标签
    soup.title    # 获取title
    soup.p    # 获取p标签
    soup.a    #  获取a标签
    
    print(soup.name)
    # [document] #soup 对象本身比较特殊,它的 name 即为 [document]
    
    print(soup.head.name)
    # head #对于其他内部标签,输出的值便为标签本身的名称
    
    print(soup.p.attrs)
    # {'class': ['title'], 'name': 'dromouse'}
    # 在这里,我们把 p 标签的所有属性打印输出了出来,得到的类型是一个字典。
    
    print(soup.p['class']) # soup.p.get('class')
    # ['title'] #还可以利用get方法,传入属性的名称,二者是等价的
    
    soup(p['class']) = "newClass"
    print(soup.p) # 可以对这些属性和内容等等进行修改
    # <p class="newClass" name="dromouse"><b>The Dormouse's story</b></p>
    
    del(soup.p['class']) # 还可以对这个属性进行删除
    print (soup.p)
    # <p name="dromouse"><b>The Dormouse's story</b></p>
    
    # 获取标签内文字
    print(soup.p.string)
    
    # tag 的 .content 属性可以将tag的子节点以列表的方式输出
    print(soup.head.contents)    # [<title>The Dormouse's story</title>]
    
    # .children它返回的不是一个 list(是一个列表生成器),不过我们可以通过遍历获取所有子节点。
    print(soup.head.children)    # <list_iterator object at 0x000002B9D7E4CFD0>
    
    # .descendants 获取所有子孙节点
    print(soup.descendants)    # 结果是一个生成器 <generator object Tag.descendants at 0x0000020AAC5B1B10>
    

    BeautifulSoup4的搜索

    # 使用find_all(name, attrs, recursive, text, **kwargs)查找
    
    # 传入name参数
    soup.find_all('p')    # 查找所有p标签
    soup.find_all('a')    # 查找所有a标签
    soup.find_all(re.compile('^p'))    # 使用正则查找所有以p打头的标签
    soup.find_all(['p', 'a'])    # 传入列表,查找所有p和a标签
    
    # 传入attrs参数
    soup.find_all(id='link1')    # 查找所有id未link1的标签,通过标签属性查找的方式适用大多数标签属性,包括id,style,title,但有 “-”,Class标签属性例外。
    soup.find_all(attrs={'class': 'sister'})
    
    # 传入text参数
    soup.find_all(text="Lacie")    # 产找所有含有内容为Lacie的对象
    soup.find_all(text=['aaa', 'bbb'])
    soup.find_all(text=re.compile("Tit"))    # 传入正则匹配
    
    # css选择查找
    soup.select('title')    # 根据标签查找
    soup.select('#link1')    # 根据Id查找
    soup.select('.sister')    # 根据类名查找
    soup.select('p #link1')    # 组合查找
    soup.select("head > title")    # 查找子标签
    soup.select('a[class="sister"]')    # 属性查找
    soup.select('title')[0].get_text()    # 使用get_text获取内容
    

    实例

    from bs4 import BeautifulSoup
    from urllib.request import *
    import json
    
    def tencent():
        url = 'https://hr.tencent.com'
        header = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36"}
        request = Request(url + '/position.php?&start=0#a', headers=header)
        response = urlopen(request)
        html = response.read()
        # with open('html.txt', 'wb+') as f:
        #     f.write(html)
    
        soup = BeautifulSoup(html, 'lxml')
        result = soup.select('tr[class="even"]')
        result2 = soup.select('tr[class="old"]')
        result.extend(result2)
        items = []
        for site in result:
            item = {}
            item['name'] = site.select('td a')[0].get_text()
            item['link'] = site.select('td a')[0].attrs['href']
            item['category'] = site.select('td')[1].get_text()
            item['recruitNumber'] = site.select('td')[2].get_text()
            item['workLocation'] = site.select('td')[3].get_text()
            item['publishTime'] = site.select('td')[4].get_text()
    
            items.append(item)
    
        line = json.dumps(items, ensure_ascii=False)
        with open('html.txt', 'w') as f:
            f.write(line)
    
    if __name__ == "__main__":
        tencent()
    
  • 相关阅读:
    I.MX6 busybox set hosname and login with root
    Linux busybox mount -a fstab
    MDEV Primer
    qtcreator cannot find -lts
    I.MX6 linux Qt 同时支持Touch、mouse
    Android ashmem hacking
    I.MX6 Android U-blox miniPCI 4G porting
    Android service binder aidl 关系
    OK335xS psplash 进度条工作原理 hacking
    设置Android默认锁定屏幕旋转
  • 原文地址:https://www.cnblogs.com/peilanluo/p/10311827.html
Copyright © 2011-2022 走看看