24 - xpath语法与多线程

Day 24

一、xpath 的基本概念和格式

1.xpath的基本概念

  1. 树:整个html(xml)代码结构就是一个树结构
  2. 节点:树结构中的每一个元素(标签)就是一个节点
  3. 根节点(根元素): html或者xml最外面的那个标签(元素)
  4. 节点内容:标签内容
  5. 节点属性:标签属性

2. xml数据格式

  • xml和json一样,是一种通用的数据格式(绝大部分编程语言都支持的数据格式)

  • xml是通过标签(元素)的标签内容和标签属性来保存数据的。

  • 示例:保存一个超市信息

  • 1)json数据

{
    "name": "永辉超市",
    "address": "肖家河大厦",
    "staffs":[
        {"name""小明", "id": "s001", "position": "收营员", "salary": 4000},
        {"name""小花", "id": "s002", "position": "促销员", "salary": 3500},
        {"name""张三", "id": "s003", "position": "保洁", "salary": 3000},
        {"name""李四", "id": "s004", "position": "收营员", "salary": 4000},
        {"name""王五", "id": "s005", "position": "售货员", "salary": 3800}
    ],
    "goodsList":[
        {"name": "泡面", "price": 3.5, "count": 120, "discount"0.9},
        {"name": "火腿肠", "price": 1.5, "count": 332, "discount"1},
        {"name": "矿泉水", "price": 2, "count": 549, "discount"1},
        {"name": "面包", "price": 5.5, "count": 29, "discount"0.85}
    ]
}

2.xml数据:

<supermarket name="永辉超市" address="肖家河大厦">
    <staffs>
        <staff  id="s001">
            <name>小明</name>
            <position>收营员</position>
            <salary>4000</salary>
        </staff>
        <staff  id="s002">
            <name>小花</name>
            <position>促销员</position>
            <salary>3500</salary>
        </staff>
        <staff  id="s003">
            <name>张三</name>
            <position>保洁</position>
            <salary>3000</salary>
        </staff>
        <staff  id="s004">
            <name>李四</name>
            <position>收营员</position>
            <salary>4000</salary>
        </staff>
        <staff  id="s005">
            <name>王五</name>
            <position>售货员</position>
            <salary>3800</salary>
        </staff>
    </staffs>
    
    <goodsList>
        <goods discount="0.9">
            <name>泡面</name>
            <price>3.5</price>
            <count>120</count>
        </goods>
        <goods>
            <name>火腿肠</name>
            <price>1.5</price>
            <count>332</count>
        </goods>
        <goods>
            <name>矿泉水</name>
            <price>2</price>
            <count>549</count>
        </goods>
        <goods discount="8.5">
            <name>面包</name>
            <price>5.5</price>
            <count>29</count>
        </goods>
    </goodsList>
</supermarket>

二、xpath的语法

1.创建树结构获取树的根节点

  • etree.XML(xml数据)
  • etree.HTML(html数据)
这里我们语法以上面我们写好的xml数据作为案例,先将文件写入文件夹
f = open('files/data.xml', encoding='utf-8')
root = etree.XML(f.read())
f.close()

2.根据xpath获取指定标签

  • 节点对象.xpath(路径):返回路径对应的所有的标签,返回值是列表,列表中的元素是标签对象(节点对象)。

  • 获取标签内容:节点对象.xpath(获取标签的路径/text()) - 获取指定路径下所有标签的标签内容

  • 路径的写法:

    1. 绝对路径: 用"/"开头的路径 - /标签在树结构中的路径 (路径必须从根节点开始写)
result = root.xpath('/supermarket/staffs/staff/name/text()')
print(result)
# ['小明', '小花', '张三', '李四', '王五']
    1. 相对路径: 路径开头用"."标签当前节点(xpath前面是谁,'.'就代表谁), "…"表示当前节点的上层节点
result = root.xpath('./staffs/staff/name/text()')
print(result)
# ['小明', '小花', '张三', '李四', '王五']

staff1 = root.xpath('./staffs/staff')[0]            # 获取第一个员工对应的staff标签
result = staff1.xpath('./name/text()')
print(result)       # ['小明']

result = staff1.xpath('../staff/name/text()')
print(result)       # ['小明', '小花', '张三', '李四', '王五']
    1. 全路径: 用"//"开头的路径 - 在整个树中获取标签
result = root.xpath('//name/text()')
print(result)
# ['小明', '小花', '张三', '李四', '王五', '泡面', '火腿肠', '矿泉水', '面包']

result = staff1.xpath('//goods/name/text()')
print(result)
# ['泡面', '火腿肠', '矿泉水', '面包']

3.获取标签内容

  • 节点对象.xpath(获取标签的路径/text()):获取指定路径下所有标签的标签内容
  • 例如我想要获取所有人的岗位信息
result = root.xpath('//position/text()')
print(result)
# ['收营员', '促销员', '保洁', '收营员', '售货员']

4.获取标签属性值

  • 节点对象.xpath(获取标签的路径/@属性名)
result = root.xpath('/supermarket/@name')
print(result)       # ['永辉超市']

result = root.xpath('//staff/@id')
print(result)
# ['s001', 's002', 's003', 's004', 's005']

5.谓语(条件)

  • a.位置相关谓语
    • [N]:第N个
    • [last()]:最后一个
    • [last()-N]; [last()-1] : 倒数第2个 、 [last()-2] :倒数第3个
    • [position()>N]、[position()<N]、[position()>=N]、[position()<=N]
result = root.xpath('//staff[1]/name/text()')
print(result)       # ['小明']

result = root.xpath('//staff[last()]/name/text()')
print(result)       # ['王五']

result = root.xpath('//staff[last()-1]/name/text()')
print(result)       # ['李四']

result = root.xpath('//staff[position()<3]/name/text()')
print(result)   # ['小明', '小花']

  • b.属性相关谓语
  • [@属性名=属性值] - 指定属性是指定值的标签
  • [@属性名] - 拥有指定属性的标签
result = root.xpath('//staff[@id="s003"]/name/text()')
print(result)
# ['张三']
result = root.xpath('//goods[@discount]/name/text()')
print(result)
# ['泡面', '面包']
  • c.子标签内容相关谓语 - 根据子标签的内容来筛选标签
    [子标签名>数据]
    [子标签名<数据]
    [子标签名>=数据]
    [子标签名<=数据]
    [子标签名=数据]
result = root.xpath('//goods[price>2]/name/text()')
print(result)

# ['泡面', '面包']
result = root.xpath('//goods[price=2]/name/text()')
print(result)
# ['矿泉水']

6 通配符 - 写路径的时候用‘*’来表示所有标签或者所有属性

result = root.xpath('//staff[1]/*/text()')
print(result)
# ['小明', '收营员', '4000']

result = root.xpath('//goods[@*]/name/text()')
print(result)
# ['泡面', '面包']

result = root.xpath('/supermarket/@*')
print(result)
# ['永辉超市', '肖家河大厦']

7.若干路径 : |

  • 路径1|路径2 - 同时获取路径1和路径2的内容
result = root.xpath('//goods/name/text()|//staff/position/text()')
print(result)

# ['收营员', '促销员', '保洁', '收营员', '售货员', '泡面', '火腿肠', '矿泉水', '面包']

三、多线程

1.进程和线程

  • 进程: 一个正在运行的应用程序就是一个进程,每个进程均运行在其专门且受保护的内存空间中

  • 线程: 线程是进程执行任务的基本单元(一个进程中的任务都是在线程中执行的)

  • 生活角度:进程就是车间,线程就是车间里面的工人。

  • 一个进程中默认有一个线程,这个线程叫主线程。

2.线程的特点

  • 如果在一个线程中执行多个任务,任务是串行执行的。(当一个程序中有很多个任务的时候,如果只有一个线程,那么程序的执行效率会很低)

3.多线程

  • 一个进程中有多个线程就是多线程。
  • 多线程执行任务的时候,多个任务可以同时(并行)执行。

4.多线程原理

  • 一个cpu同一时间只能调度一个线程,多线程其实是cpu快速的在多个线程之间进行切换,造成多个线程同时执行的假象。(提高cpu利用率)

5.Python使用多线程的方法

  • 一个进程默认只有一个线程,这个线程叫主线程,主线程以外的线程都叫子线程。
  • Python程序中如果需要子线程,必须创建线程类(Thread)的对象。
  • 例如 我想下载3部电影
from threading import Thread
from time import sleep
from datetime import datetime


def download(name):
    print(f'{name}开始下载:{datetime.now()}')
    sleep(2)
    print(f'{name}下载结束:{datetime.now()}')


if __name__ == '__main__':
    # 情况1:在一个线程(主线程)中下载3个电影
    download('肖生克救赎')
    download('霸王别姬')
    download('阿甘正传')
    
    # 如果下载一部电影要2分钟  那么这3部要花我6分钟
  • 这种情况下我就可以创建3个子线程分别下载3部电影

  • 线程对象 = Thread(target=函数, args=元组)
    +a.函数 - 可以是普通函数函数名,也可以是匿名函数。这个函数就是需要子线程中执行的任务。
    +b.元组 - 元组中的元素就是在子线程中调用target对应的函数的时候需要的参数

   t1 = Thread(target=download, args=('肖生克救赎',))
    t2 = Thread(target=download, args=('霸王别姬',))
    t3 = Thread(target=download, args=('阿甘正传',))

# 启动线程 - 让子线程调用对应的函数
    t1.start()
    t2.start()
    t3.start()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值