Python学习笔记--Python 爬虫入门 -17-8 正则,xml+xpath+lxml

# 页面解析和数据提取
- 结构数据: 先有的结构,在谈数据
    - JSON文件
        - JSON Path
        - 转换成Python类型进行操作(json类)
    - XML文件
        - 转换成python类型(xmltodict)
        - XPath
        - CSS选择器
        - 正则
- 非结构化数据:先有数据,再谈结构
    - 文本
    - 电话号码
    - 邮箱地址
        - 通常处理此类数据,使用正则表达式
    - Html文件
        - 正则
        - XPath
        - CSS选择器
       
# 正则表达式
- 一套规则,可以在字符串文本中进行搜查替换等
- 案例v23,re的基本使用流程

import  re

"""
正则 re
使用步骤:
1.compile 函数将正则表达式的字符串生成一个Pattern 对象
2.通过Pattern 对象的一些方法对文本进行匹配,匹配结果是一个Match 对象
3.用Match 对象的方法,对结果操作
"""

if __name__ == '__main__':
    s = r"\d+ \d+"
    # s = r'(\w+) (\w+)'
    pattern = re.compile(s)
    # m = pattern.match("12 1one34two56three")
    m = pattern.match("one two three four")
    print(type(m))#<class '_sre.SRE_Match'>
    print(m) #<_sre.SRE_Match object; span=(0, 4), match='12 1'>
    print(m.group(0)) #12 1
    # print(m.start(0)) #0
    # print(m.end(0)) #4
    # print(m.span(0))

    print(m.groups())


- 案例v24,match的基本使用

'''
正则结果Match的使用案例
'''

import re

# 以下正则分成了两个组,以小括号为单位
s = r'([a-z]+) ([a-z]+)'
pattern = re.compile(s, re.I) # s.I表示忽略大小写

m = pattern.match("Hello world wide web")

# goup(0)表示返回匹配成功的整个子串
s = m.group(0)
print(s)

a = m.span(0) # 返回匹配成功的 整个子串的跨度
print(a)

# gourp(1)表示返回的第一个分组匹配成功的子串
s = m.group(1)
print(s)

a = m.span(1) # 返回匹配成功的第一个子串的跨度
print(a)


s = m.groups() #等价于m.gourp(1), m.group(2).......
print(s)


- 正则常用方法:
    - match: 从开始位置开始查找,一次匹配
    - search:从任何位置查找,一次匹配, 案例v25

"""
search
"""
import  re

s = r'\d+'
pattern  = re.compile(s)
m = pattern.search("one12two34three56")
print(m.group())
# 参数表明搜索的起始范围
m = pattern.search("one12two34three56",10,40)
print(m.group())


    - findall: 全部匹配,返回列表, 案例v26

"""
findall 用法
"""
import  re
parttern = re.compile(r"\d+")

m = parttern.findall("i am 18 years and 185 high")

print(type(m)) #<class 'list'>
s = [i for i in m ]
print(s)

mi = parttern.finditer("i am 18 years and 185 high")
print(type(mi)) #<class 'callable_iterator'>

im = [i.group() for i in mi]
print(im) #['18', '185']


    - finditer: 全部匹配,返回迭代器, 案例v26
    - split: 分割字符串,返回列表
    - sub:替换
- 匹配中文
    - 中文unicode范围主要在[u4e00-u9fa5]
    - 案例v27
    

"""
匹配中文
"""

import  re
s = u'你好 世界'
pattern  = re.compile(r'[\u4e00-\u9fa5]+')

m = pattern.findall(s)

print(m)


- 贪婪与非贪婪模式
    - 贪婪模式: 在整个表达式匹配成功的前提下,尽可能多的匹配
    - 非贪婪模式: xxxxxxxxxxxxxxxxxxxxxx, 尽可能少的匹配
    - python里面数量词默认是贪婪模式
    - 例如:
        - 查找文本abbbbbbccc
        - re是 ab*
        - 贪婪模式: 结果是abbbbbb
        - 非贪婪: 结果是a
# XML
- XML(EXtensibleMarkupLanguage)   
-    http://www.w3school.com.cn/xml/index.asp
- 概念:父节点,子节点,先辈节点,兄弟节点,后代节点

# XPath
- XPath(XML Path Language), 是一门在XML文档中查找信息的语言,
- 官方文档: http://www.w3school.com.cn/xpath/index.asp
- XPath开发工具
    - 开元的XPath表达式工具: XMLQuire
    - chrome插件: Xpath Helper
    - Firefox插件: XPath CHecker
    
- 常用路径表达式:
    - nodename: 选取此节点的所有子节点
    - /: 从根节点开始选
    - //: 选取元素,而不考虑元素的具体为止
    - .:  当前节点
    - ..:父节点
    - @: 选取属性
    - 案例:
        - booksotre: 选取bookstore下的所有子节点
        - /booksotre: 选取根元素
        - booksotre/book: 选取bookstore的所有为book的子元素
        - //book: 选取book子元素
        - //@lang:选取名称为lang的所有属性
- 谓语(Predicates)
    - 谓语用来查找某个特定的节点,被向前在方括号中
    - /bookstore/book[1]: 选取第一个属于bookstore下叫book的元素
    - /bookstore/book[last()]: 选取最后一个属于bookstore下叫book的元素
    - /bookstore/book[last()-1]: 选取倒数第二个属于bookstore下叫book的元素
    - /bookstore/book[position()<3]: 选取属于bookstore下叫book的前两个元素
    - /bookstore/book[@lang]: 选取属于bookstore下叫book的,含有属性lang元素
    - /bookstore/book[@lang="cn"]: 选取属于bookstore下叫book的,含有属性lang的值是cn的元素
    - /bookstore/book[@price < 90]: 选取属于bookstore下叫book的,含有属性price的,且值小于90的元素
    - /bookstore/book[@price < 90]/title: 选取属于bookstore下叫book的,含有属性price的,且值小于90的元素的子元素title
    
- 通配符
    - `*` : 任何元素节点
    - @*: 匹配任何属性节点
    - node(): 匹配任何类型的节点
- 选取多个路径
    - //book/tile  | //book/author : 选取book元素中的title和author元素
    - //tile | //price: 选取文档中所有的title和price元素
  
# lxml
- python的HTML/XML的解析器
- 官方文档:   http://lxml.de/index.html
- 功能:
    - 解析HTML,案例v29.py

"""
安装lxml
"""
from  lxml import  etree
"""
用lxml 解析HTML代码
"""
text ='''
<div>
    <ul>
        <li class="item-0"> <a href="0.html"> first item </a></li>
        <li class="item-1"> <a href="1.html"> first item </a></li>
        <li class="item-2"> <a href="2.html"> first item </a></li>
        <li class="item-3"> <a href="3.html"> first item </a></li>
        <li class="item-4"> <a href="4.html"> first item </a></li>
        <li class="item-5"> <a href="5.html"> first item </a>
    </ul>
</div>
'''

# 利用etree.HTML 把字符串解析成HTML文档
html = etree.HTML(text)
s = etree.tostring(html)

#自动补全</li> 标签
print(s.decode())


    - 文件读取,案例v30.html, v31.py

<?xml version="1.0" encoding="utf-8"?>

<bookstore>
    <book category="cooking">
        <title lang="en">Everyday Italian</title>
        <author>Gidada De</author>
        <year>2018</year>
        <price>23</price>
    </book>


    <book category="education">
        <title lang="en">Python is Python</title>
        <author>Food War</author>
        <year>2008</year>
        <price>83</price>
    </book>

    <book category="sport">
        <title lang="en">Running</title>
        <author>Klaus Kuka</author>
        <year>2010</year>
        <price>43</price>
    </book>

</bookstore>
from lxml import  etree

html = etree.parse("./v30.html")

rst = etree.tostring(html,pretty_print=True)

print(rst)


    - etree和XPath的配合使用, 案例v32.py

from lxml import  etree
html = etree.parse("./v30.html")
# print(type(html)) #<class 'lxml.etree._ElementTree'>
# print(html) #<lxml.etree._ElementTree object at 0x0000018FA2F4E348>

rst = html.xpath("//book")
# print(type(rst)) #<class 'list'>
# print(rst) #[<Element book at 0x2369dd2e2c8>, <Element book at 0x2369dd2e408>, <Element book at 0x2369dd2e448>]
# bs = [i.text  for i in rst]
# print(bs)

rst1 = html.xpath("//book[@category='sport']")
# print(type(rst1)) #<class 'list'>
# print(rst1) #[<Element book at 0x22670e9e3c8>]




rst2 = html.xpath("//book[@category='sport']/year")
# print(type(rst2)) #<class 'list'>
# print(rst2) #[<Element book at 0x22670e9e3c8>]
rst2 = rst2[0]

print(rst2.tag)
print(rst2.text)

猜你喜欢

转载自blog.csdn.net/u013985879/article/details/82562370
今日推荐