Python正则和XPATH以及CSS选择器

原创
2019/06/22 01:35
阅读数 450

Python的正则表达式

- 非结构化数据    现有数据,再有介机构 如: HTML
- 结构化输数据    现有结构,再有数据   如: JSON

正则表达式


贪婪模式:
        在匹配成功的情况下,才有贪婪与非贪婪

        尽可能多的匹配
        如:
            preg = 'abbbb';
            re.finall('ab*', preg)
        结果:
            ['abbbb']

非贪婪模式:
        在匹配成功的情况下,才有贪婪与非贪婪

        尽可能少的匹配
            preg = 'abbbb';
            # *标识前面这个可以,匹配0次或多次, 可以有也可以没有.
            # 前面的* 匹配成功了之后, ?前面这个启动非贪婪模式, 尽可能少的匹配(即为不匹配)
            re.finall('ab*?', preg)
            结果:
                ['a']

            # 如果不明白*?的话可以对比一下+,匹配一次或多次
            # 而一旦+匹配成功, ?设置前面为,尽可能少的匹配
            re.finall('ab+?', preg)
            记过:
                ['ab']

先决条件

# _*_ encoding:utf-8 _*_
# 引入正则表达式Module
import re


# re.compile() 可以不用这个方法, 但是compile是起到了编译作用, 使正则的匹配速度更快一点
# re.compile() 把正则表达式的字符串编译成一个 pattern 对象
# r关键字对特殊字符需要转义
preg = re.compile(r'\d+')

  • match(string, pos, endpos)
match从字符串的开头(或指定位置)进行匹配,如果在开头没找到就返回None,
只匹配一次,匹配到结果就不在匹配了

# 匹配条件
    result = preg.march('one123two456')
    print(result)

# 结果
    None

# 修正,从第3个开始匹配,匹配到第10个
    result = preg.march('one123two456', 3, 10)
    print(result)
结果
    返回正则对象: <_sre.SRE_Match object; span=(3, 6), match='123'>
    使用: result.group()获取结果为: 123

  • sarch(string, pos, endpos)
search 匹配整个字符串,也可以指定匹配的位置
只匹配一次,匹配到结果就不在匹配了

# 匹配条件
result = pattern.search('one123two456')

# 结果
    返回正则对象: <_sre.SRE_Match object; span=(3, 6), match='123'>
    使用: result.group()获取结果为: 123

  • finall(string, pos, endpos)
获取所有的匹配结果

# 匹配条件
    result = pattern.findall('one123two456')
    print(result)

# 结果
    失败: 返回一个空list. 如: []
    成功: 返回一个包含所有的list
    ['123', '456']

  • sub(pattern, repl, string, count=0, flags=0)
替换匹配到的字符串

# 将以下几个HTML标签替换为空,同时将结果赋值到iterm中
re.sub(r'&\w+;|<p>|</p>|<br />', '', iterm)

  • 注释
二.常用的re函数:
方法/属性 	作用
re.match(pattern, string, flags=0) 	从字符串的起始位置匹配,如果起始位置匹配不成功的话,match()就返回none
re.search(pattern, string, flags=0) 	扫描整个字符串并返回第一个成功的匹配
re.findall(pattern, string, flags=0) 	找到RE匹配的所有字符串,并把他们作为一个列表返回
re.finditer(pattern, string, flags=0) 	找到RE匹配的所有字符串,并把他们作为一个迭代器返回
re.sub(pattern, repl, string, count=0, flags=0) 	替换匹配到的字符串

函数参数说明:
pattern:匹配的正则表达式
string:要匹配的字符串
flags:标记为,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
repl:替换的字符串,也可作为一个函数
count:模式匹配后替换的最大次数,默认0表示替换所有匹配

xpath

  • xpath踩到的坑
URL:http://blog.jobbole.com/110287/ 获取文章标题

Chrome复制的xpath
//*[@id="post-110287"]/div[1]/h1
Firefox复制的xapth
/html/body/div[3]/div[3]/div[1]/div[1]/h1

理论上来讲,两个都没问题, 通过F12控制台查看也都没有问题,
虽然写法不同,但是看起来没有问题.
但是在实际使用中发现Firefox提供的并不能用
经过分析发现:
    Firefox提供的是绝对路径, 即从根开始,而且提供的是和控制台一样的代码顺序.
    而且在body/div并不是第三个,应该是第一个,前面两个是JS生成的.
    实际上是应该按照源码,查看,即在页面点击查看源码,这里的代码才是对的.
    chrome提供的是从ID开始,ID和我们想要的元素比较近,所以没有出问题.
    平时使用当中,应该注意这一点.
    
    结论:
        我们在平时使用当中, 需要提取xpath时,通过控制台看代码得时候,要注意HTML的颜色提示.
        js生成的代码不能算在内, 必要的时候可以通过查看页面源码来对比浏览器给得xpath对不对.
        一般情况下, 我们也不要从根开始拼节点.


  • 语法
article         选取所有article元素的子节点
/article        选取根元素article
article/a       选取所有属于article的子元素的a元素
//div           选取所有div子元素(不论出现在文档何种位置)
article//div    选取所有属于article元素的后代的div元素
//@class        选取所有名为class的属性
  • 语法- 谓语
/article/div[1]         选取属于article子元素的第一个元素
/article/div[last()]    选取属于article子元素的最后一个元素
/article/div[last()-1]  选取属于article子元素的倒数第二个元素
//div[@lang]            选取所有拥有lang属性的div元素
//div[@lang='eng']      选取所有lang属性为eng的div元素

/div/*                  选取属于div元素的所有子元素
//*                     选取所有元素
//div[@*]               选取所有带有属性的title元素
/div/a|//div/p          选取所有div元素的a和p元素
//span|//ul             选取文档中的span和ul元素
article/div/p|//span    选取所有属于article元素的div元素的p元素以及文档中的所有的span元素
  • 函数
text()      获取文字内容
contains()  获取匹配到的元素
如:
//span[contains(@class, 'vote-post-up')]
获取class中含有vote-post-up名的class, 当一个class有多个名字的时候用这个特别好

  • 常用
/从根节点选取
//从匹配选择当前节点匹配所有
.选择当前节点
@选取HTML的属性 class id src href

xpath 是可以运算的
| 并集 + -

  • 例子
//book # 选取所有的book元素, 不考虑位置
//@ddd # 选取所有名为ddd的属性

# 匹配该含有该class属性的所有div下的所有a节点的href属性
//div[@class="threadlist_title pull_left j_th_tit "]//a/@href

# 匹配所有div下的img含有BED_Image属性的src属性
//div/img[@class="BDE_Image"]//@src

CSS选择器

  • 常用语法
*                   选择所有节点
#container          选择ID为containerd的节点
.container          选取所有class为container的节点
.containser.next    选取同时含有.containser.next 的class
li a                选取所有li下的a节点
ul + p              选择ul后面的第一个p元素
div#container > ul  选取id为container的div的第一个ul子元素

ul ~ p                      选取与ul相邻的所有p元素
a[title]                    选取所有title属性的a元素
a[href="http://jobole.com"] 选取所有href属性为jobbole.com值的a元素
a[href*="jobbole"]          选取所有href属性包含jobbole的a元素
a[href^="http"]             选取所有href属性值以http开头的a元素
a[href$=".jpg"]             选取所有href属性值以.jpg结尾的a元素
input[type=radio]:checked   选取选中的radio的元素

div:not(#container)         选取所有ID为非container的div元素
li:nth-child(3)             选取子类中的第三个li元素
tr:nth-child(2n)            选取子类中的第偶数个tr

  • CSS常用函数(伪类选择器)
::text          获取文字内容
::attr(属性)    获取指定属性的值
展开阅读全文
加载中

作者的其它热门文章

打赏
0
0 收藏
分享
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部