(1)结构数据:先有的结构,再谈数据
-JSON文件
-JSON Path
-转换成python类型进行操作(json类)
-XML文件
-转换成python类型(xmltodict)
-XPath
-CSS选择器
-正则
(2)非结构化数据:先有数据,再谈结构
-文本、电话号码、邮箱地址
-通常处理此类数据,使用正则表达式
-Html文件
-正则
-XPath
-CSS选择器
(1)一套规则,可以在字符串文本中进行搜索替换等
在正则表达式中,可以对过滤到的字符串进行分组。分组使用圆括号的方式。
group
:和group(0)
是等价的,返回的是整个满足条件的字符串。groups
:返回的是里面的子组。索引从1开始。group(1)
:返回的是第一个子组,可以传入多个。(2)-re的基本使用流程
'''
使用大致步骤:
1、compile函数将正则表达式的字符串变为一个pattern对象
2、通过pattern对象的一些方法对文本进行匹配,匹配结果是一个Match对象
3、用Match对象的方法对结果进行操纵
'''
import re
#\d表示以数字
#后面+号表示这个数字可以出现一次或者多次
s = r"\d+" #r表示后面是原生字符串,后面不需要转义
#返回pattern对象
pattern = re.compile(s)
#返回一个match对象,后面的位置参数含义是从哪个位置开始查找,找到哪个位置结束
#默认找到一个匹配就返回
m = pattern.match("one12two34three56",3,10)
print(type(m))
#默认匹配从头部开始,所以此次结果为None
print(m)
print(m.group())
print(m.start(0))
print(m.end(0))
print(m.span(0))
运行:
12
3
5
(3, 5)
-match的基本使用
'''
正则结果的match的使用案例
'''
import re
#以下正则分成了两个组,以小括号为单位
s = r'([a-z]+) ([a-z]+) ([a-z]+)'
pattern = re.compile(s,re.I) #re.I表示忽略大小写
m = pattern.match("Hello World wide web")
#group(0) 表示返回匹配成功的整个子串
s = m.group(0)
print(s)
a = m.span(0) #返回匹配成功整个子串的跨度
print(a)
#group(1)表示返回的第一个分组匹配成功的子串
s = m.group(1)
print(s)
a = m.span(1) #返回匹配成功的第一个子串的跨度
print(a)
s = m.groups() #等价于m.group(1),m.group(2)....
print(s)
运行:
Hello World wide
(0, 16)
Hello
(0, 5)
('Hello', 'World', 'wide')
(3)正则常用方法
-match:从开始位置开始查找,一次匹配
-search:从任何位置查找,一次匹配
-findall:全部匹配,返回列表
-finditer:全部匹配,返回迭代器
-split:分隔字符串,返回列表
-sub :替换
'''
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
'''
import re
pattern = re.compile(r'\d+')
s = pattern.findall("i am 18 years old and 185 high")
print(s)
s = pattern.finditer("i am 18 years old and 185 high")
print(type(s))
for i in s:
print(i.group())
运行:
12
56
['18', '185']
18
185
(4)匹配中文
-中文unicode范围主要是在[u4e00-u9fa5]
'''
中文unicode案例
'''
import re
hello = u'你好,世界'
pattern = re.compile(r'[\u4e00-\u9fa5]+')
m = pattern.findall(hello)
print(m)
运行:
['你好', '世界']
(5)贪婪与非贪婪模式
-贪婪模式:在整个表达式匹配成功的前提下,尽可能多的匹配
-非贪婪模式:xxxxxx,尽可能少的匹配
-python里面数量词默认是贪婪模式
-例如:
-查找文本abbbbccc
-re是ab*
-贪婪模式:abbbb
-非贪婪模式:a
-XML(ExtensibleMarkupLanguage)
-http://www.w3school.com.cn/xml/index.asp
-概念:父节点、子节点、先辈节点、兄弟节点、后代节点
>
Everyday Italian
Gidada De
2018
23
Running
Klaus Kuka
2010
43
Python is Python
Food War
2008
83
(1)XPath(XML Path Language),是一门在XML文档中查找信息的语言
-官方文档:http://www.w3school.com.cn/xpath/index.asp
-XPath开发工具
-开元的XPath表达式工具:XMLQuire
-chrome插件:Xpath Helper
-Firefox插件:XPath CHecker
(2)常用路径表达式
-nodename:选取此节点的所有子节点
- / :从根节点开始选
- // :选取元素,而不考虑元素的具体位置
- . :当前节点
- @ :选取属性
(3)案例:
-bookstore:选取bookstore下的所有子节点
-/bookstore:选取根元素
-bookstore/book:选取bookstore的所有为book的子元素
- //book:选取book子元素
- //@lang:选取名称为lNG的所有属性
(4)谓语(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
(5)通配符
- ‘*’:任何元素节点
- @*:匹配任何属性节点
-node():匹配任何类型的节点
(6)选取多个路径
-//book/title | //book/author:选取book元素中的title和author元素
-//title | //price:选取文档中所有的title和price元素
(1)lxml库
-python的HTML/XML的解析器
-官方文档:http://lxml.de/index.html
-功能:
-解析HTML,
'''
安装lxml
'''
from lxml import etree
'''
用lxml来解析HTML代码
'''
text = '''
'''
#利用etree.HTML把字符串解析成HTML文档
html = etree.HTML(text)
s = etree.tostring(html)
print(s)
运行:
b'\n \n first item \n first item \n first item \n first item \n first item \n first item \n \n\n'
--文件读取
from lxml import etree
#只能读取xml格式内容,html报错
html = etree.parse("./v31.html")
rst = etree.tostring(html,pretty_print=True)
print(rst)
-etree和XPath的配合使用
from lxml import etree
#只能读取xml格式内容,html报错
html = etree.parse("./v31.html")
print(type(html))
rst = html.xpath('//book')
print(type(rst))
print(rst)
#xpath的意思是查找带有category属性值为sport的book元素
rst = html.xpath('//book[@category="sport"]')
print(type(rst))
print(rst)
#xpath的意思是查找带有category属性值为sport的book元素下的year元素
rst = html.xpath('//book[@category="sport"]/year')
rst = rst[0]
print(type(rst))
print(rst.tag)
print(rst.text)
运行:
[, , ]
[]
year
2010
-现在使用BeautifulSoup4
-http://beautifulsoup.readthedocs.io/zh_CN/v4.4.0/
-几个常用提取信息工具的比较:
-正则:很快,不好用,不用安装
-beautifilsoup:慢,使用简单,安装简单
-lxml:比较快,使用简单,安装一般
from urllib import request
from bs4 import BeautifulSoup
url = 'http://www.baidu.com'
rsp = request.urlopen(url)
content = rsp.read()
soup = BeautifulSoup(content,'lxml')
#bs自动转码
content = soup.prettify()
print(content)
(1)四大对象
-Tag
-NavigableString
-BeautifulSoup
-Comment
-Tag
-对应Html中的标签
-可以通过soup.tag_name
-tag两个重要属性:name、attrs
from urllib import request
from bs4 import BeautifulSoup
url = 'http://www.baidu.com'
rsp = request.urlopen(url)
content = rsp.read()
soup = BeautifulSoup(content,'lxml')
#bs自动转码
content = soup.prettify()
#print(soup.head)
print('==' * 12)
print(soup.link)
print(soup.link.name)
print(soup.link.attrs['type'])
#可以修改,因为已经得到并放进了内存中
soup.link.attrs['type'] = 'hahaha'
print(soup.link)
print('==' * 12)
运行:
========================
link
image/x-icon
========================
-NavigableString 对应内容值
-BeautifulSoup
-表示的是一个文档的内容,大部分可以把他当作tag对象
-一般我们可以用soup来表示
from urllib import request
from bs4 import BeautifulSoup
url = 'http://www.baidu.com'
rsp = request.urlopen(url)
content = rsp.read()
soup = BeautifulSoup(content,'lxml')
#bs自动转码
content = soup.prettify()
print('==' * 12)
print(soup.link)
print(soup.link.name)
print(soup.link.attrs['type'])
#可以修改,因为已经得到并放进了内存中
soup.link.attrs['type'] = 'hahaha'
print(soup.link)
print('==' * 12)
#NavigableString
print(soup.title)
print(soup.title.name)
print(soup.title.attrs)
print(soup.title.string)
print("==" * 12)
print(soup.name)
print(soup.attrs)
运行:
========================
link
image/x-icon
========================
百度一下,你就知道
title
{}
百度一下,你就知道
========================
[document]
{}
[document]
-Comment
-特殊类型的NavigableString类
-对其输出,则内容不包括注释符号
(2)遍历文档对象
-contents:tag的子节点以列表的方式给出
-children:子节点以迭代器形式返回
-descendants:所子孙节点
-string
from urllib import request
from bs4 import BeautifulSoup
url = 'http://www.baidu.com'
rsp = request.urlopen(url)
content = rsp.read()
soup = BeautifulSoup(content,'lxml')
#bs自动转码
content = soup.prettify()
print('==' * 12)
print(soup.link)
print(soup.link.name)
print(soup.link.attrs['type'])
#可以修改,因为已经得到并放进了内存中
soup.link.attrs['type'] = 'hahaha'
print(soup.link)
print('==' * 12)
#NavigableString
print(soup.title)
print(soup.title.name)
print(soup.title.attrs)
print(soup.title.string)
print("==" * 12)
print(soup.name)
print(soup.attrs)
运行:
========================
百度一下,你就知道
========================
(3)搜索文档对象
-find_all(name,attrs,recursive,text,**kwargs)
-name:按照那个字符串搜索,可以传入的内容为
-字符串、正则表达式、列表
-keyworld参数,可以用来表示属性
-text:对应tag的文本值
from urllib import request
from bs4 import BeautifulSoup
url = 'http://www.baidu.com'
rsp = request.urlopen(url)
content = rsp.read()
soup = BeautifulSoup(content,'lxml')
#print(soup.name)
print("==" * 12)
#tags = soup.find_all(name="meta")
#正则
import re
tags = soup.find_all(re.compile("^me"),content="always")
for tag in tags:
print(tag)
print("==" * 12)
运行:
========================
========================
(4)css选择器
-使用soup.select,返回一个列表
-通过标签名称:soup.select("title")
-通过类名:soup.select(".content")
-id查找:soup.select("#name_id")
-组合查找:soup.select("div #input_content")
-属性查找:soup.select("img[class='photo']")
-获取tag内容:tag.get_text
from urllib import request
from bs4 import BeautifulSoup
url = 'http://www.baidu.com'
rsp = request.urlopen(url)
content = rsp.read()
soup = BeautifulSoup(content,'lxml')
print(soup.prettify())
print("==" * 12)
titles = soup.select("title")
print(titles[0])
print("==" * 12)
metas = soup.select("meta[content='always']")
print(metas[0])
print("==" * 12)
运行:
百度一下,你就知道
========================
百度一下,你就知道
========================
========================