Python实用小技巧(七)

本文介绍了Python中使用lxml库进行XPath数据提取的技巧,包括string与text的区别、路径表达式以及常用函数的使用。同时展示了如何利用XPath处理嵌套元素、选取特定属性以及字符串操作。此外,还讲解了urllib库在处理自动编码转化中的应用,确保正确解码网页内容。
摘要由CSDN通过智能技术生成

Python实用小技巧

1. Xpath中string的用法以及与text的区别

Xpath提取数据的时候,最常使用的就是Xpath的text()方法,该方法可以提取当前元素的信息,但是某些元素下包含很多嵌套元素,想一并的提取出来,这时候就用到了string(.)方法。

from lxml import etree

s = """
<div>
    <ul class="show">这里是show
        <li>275万购昌平邻铁三居 总价20万买一居</li>
        <li>00万内购五环三居 140万安家东三环</li>
        <li>北京首现零首付楼盘 53万购东5环50平</li>
        <li>京楼盘直降5000 中信府 公园楼王现房</li>
    </ul>
</div>
"""

html = etree.HTML(s)
result = html.xpath("//div/ul[@class='show']")[0]
print(result.xpath('string(.)'))
print('--------------------------------------')
print(result.text)

使用string(.)会把当前节点下面的所有文本都提取出来,这种提取是无视层级的。text就只能提取当前节点的文本,后代节点的文本是无法获取到的。

2. Xpath中路径表达式

/div -------> 从根节点开始选取div节点
//a --------> 选取文档中所有a节点,不考虑其位置
@class --------> 选取名为class的属性
. ------------> 选取当前节点
.. -------------> 选取父节点
/div/p ------------> 从根节点开始选取div节点下的p节点
/div/p[2]/ul -------------> 从根节点开始选取div节点下的的二个p节点下的ul节点
//div[@class=‘text’] ---------------------> 选取所有class属性名为text的div节点
//* ---------------> 选取文档中所有元素
//@* ---------------> 选取文档中所有带属性的元素
: ------------------> 命名空间分隔符;将命名空间前缀与元素名或属性名分隔。
() ------------------> 括号运算符(优先级最高),强制运算优先级。
[] --------------------> 应用筛选模式(即谓词,包括"过滤表达式""轴(向前/向后)")。
| ---------------------->两个节点集合的联合,如://messages/message/to | //messages/message/cc

3. Xpath中常用函数介绍

from lxml import etree

s = """
<div>
    <ul class="show">这里是show
        <li>275万购昌平邻铁三居 总价20万买一居</li>
        <li>00万内购五环三居 140万安家东三环</li>
        <li>北京首现零首付楼盘 53万购东5环50平</li>
        <li>京楼盘直降5000 中信府 公园楼王现房</li>
    </ul>
    <ul class='ul1'>1</ul>
    <ul class='stea'>2</ul>
    <ul class='test'>Hello djksladjfkljlasdjflasjkdlflasdlk</ul>
    <ul class='all4'>ajsdkfjksldadkfasjHellojflladkfjaklds</ul>
    <ul></ul>
    <ul></ul>
    <ul></ul>
</div>
"""

html = etree.HTML(s)
# starts-with:匹配以为xx开头的东西
# 案例:匹配以s开头的作为类名的元素
result = html.xpath('//div/ul[starts-with(@class,"s")]')
print(result)
# not:匹配不包含某个属性的元素
# 案例:匹配不包含类名的元素
result = html.xpath('//div/ul[not(@class)]')
print(result)
# concat:字符串连接
# 案例:拼接两个元素的内容
result = html.xpath('concat(//div/ul[@class="ul1"]/text(),//div/ul[@class="stea"]/text())')
print(result)
# contains 判断是否含有某个内容
# 案例:获取文本中包含了Hello的元素
result = html.xpath('//div/ul[contains(text(),"Hello")]')
print(result)

4. urllib的自动编码转化

import urllib.request
from io import BytesIO
import gzip
import re


def auto_charset(response):
    """
    :param response: 传入响应的结果,自动进行编码转化
    :return: 转化好后的网页
    """
    # 查看请求头
    # print(response.headers)
    encoding = response.headers.get('Content-Encoding')
    if encoding and "gzip" in encoding:  # 如果是gzip格式,就解压转化成正常格式
        f = gzip.GzipFile(fileobj=BytesIO(resp.read()))
        return f.read().decode('utf-8')
    elif response.headers.get("Content-Type") and 'charset' in response.headers.get(
            "Content-Type"):  # 如果charset在Content-type里面
        # 获取网页判断,网页编码通常放在Content-Type的charset里面,获取到这个之后就知道网页采用的编码了,
        # 然后就可以使用对应的编码进行解码,这里使用正则进行提取
        charset = response.headers.get("Content-Type")
        charset = re.search(r'charset=(.+?)(;|$)', charset).group(1)
        return response.read().decode(charset)
    else:  # 如果charset里面没有编码,默认使用utf-8进行编码
        # 提取读取获取出来的内容
        text = response.read()
        # 加入异常处理,如果默认UTF-8编码无法解码,则切换至GBK编码进行转化
        try:
            return text.decode('utf-8')
        except UnicodeDecodeError as e:
            return text.decode('gbk')


# 这里切换URL地址
url = 'https://www.biqooge.com/'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36 Edg/91.0.864.59',
}
# 添加请求头操作
request = urllib.request.Request(url, headers=headers)
resp = urllib.request.urlopen(request)
print(auto_charset(resp))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值