目录
1. 数据分类
结构化数据:json,xml等
处理方式:转化为python类型
非结构化数据:HTML
处理方式:正则表达式、xpath、bs4
2. JSON
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,它使得人们很容易的进行阅读和编写。同时也方便了机器进行解析和生成。适用于进行数据交互的场景,比如网站前台与后台之间的数据交互。
2.1 json数据转换
json.dumps:python类型转化为json字符串
json_str = json.dumps(mydict,indent=2,ensure_ascii=False) indent实现换行和空格 ensure_ascii=False实现让中文写入的时候保持为中文
json.loads:json字符串转化为python的数据类型
my_dict = json.loads(json_str)
json.dump:把python类型写入类文件对象
with open("temp.txt","w") as f: json.dump(mydict,f,ensure_ascii=False,indent=2)
json.load:类文件对象中的json字符串转化为python类型
with open("temp.txt","r") as f: my_dict = json.load(f)
3. 正则表达式
用事先定义好的一些特定字符、及这些特定字符的组合,组成一个规则字符串,这个规则字符串用来表达对字符串的一种过滤逻辑
3.1 re模块
1.使用 pip install re 下载模块
2.使用 import re 导入模块
3.1.1 常见方法
-
pattern.match(从头查找匹配一个)返回一个match对象,找不到返回None
-
pattern.search(任意位置匹配一个)返回一个search对象,找不到返回None
-
pattern.findall(全部匹配)返回一个列表,没有就是空列表
-
pattern.sub(替换)
-
re.compile(编译)
-
返回一个模型P,具有和re一样的方法,但是传递的参数不同
-
匹配模式需要传到compile中
-
-
re的修饰符
修饰符 | 描述 |
---|---|
re.I | 使匹配对大小写不敏感 |
re.L | 做本地化识别(locale-aware)匹配 |
re.M | 多行匹配,影响 ^ 和 $ |
re.S | 使 . 匹配包括换行在内的所有字符 |
re.U | 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B. |
re.X | 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。 |
3.1.2 单字符匹配
代码 | 功能 |
---|---|
. | 匹配任意1个字符(除了\n) |
[ ] | 匹配[ ]中列举的字符 |
\d | 匹配数字,即0-9 |
\D | 匹配非数字,即不是数字 |
\s | 匹配空白,即 空格,tab键 |
\S | 匹配非空白 |
\w | 匹配非特殊字符,即a-z、A-Z、0-9、_、汉字 |
\W | 匹配特殊字符,即非字母、非数字、非汉字 |
3.1.3 多字符匹配
代码 | 功能 |
---|---|
* | 匹配前一个字符出现0次或者无限次,即可有可无 |
+ | 匹配前一个字符出现1次或者无限次,即至少有1次 |
? | 匹配前一个字符出现1次或者0次,即要么有1次,要么没有 |
{m} | 匹配前一个字符出现m次 |
{m,n} | 匹配前一个字符出现从m到n次 |
3.1.4 匹配开头和结尾
代码 | 功能 |
---|---|
^ | 匹配字符串开头 |
$ | 匹配字符串结尾 |
3.1.5 分组匹配
代码 | 功能 |
---|---|
| | 匹配左右任意一个表达式 |
(ab) | 将括号中字符作为一个分组 |
\num | 引用分组num匹配到的字符串 |
(?P) | 分组起别名 |
(?P=name) | 引用别名为name分组匹配到的字符串 |
3.1.6 贪婪非贪婪匹配
功能 | 描述 |
---|---|
贪婪匹配 | 正则表达式一般趋向于最大长度匹配,默认贪婪匹配。 |
非贪婪匹配 | 尽量少的匹配字符 在量词后面直接加上一个 ? |
4. Xpath
XPath (XML Path Language) 是一门在 HTML\XML 文档中查找信息的语言,可用来在 HTML\XML 文档中对元素和属性进行遍历。
4.1 语法
表达式 | 描述 |
---|---|
nodename | 选中该元素。 |
/ | 从根节点选取、或者是元素和元素间的过渡。 |
// | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。 |
. | 选取当前节点。 |
.. | 选取当前节点的父节点。 |
@ | 选取属性。 |
text() | 选取文本。 |
4.2 查找特定节点
路径表达式 | 结果 |
---|---|
//span[@class="first"] | 选择class属性值为first的所有span标签 |
//ul/span[1] | 选取属于 ul子标签的第一个 span标签。 |
//ul/span[last()] | 选取属于 ul子标签的最后一个 span标签。 |
//ul/spanlast()-1] | 选取属于 ul子标签的倒数第二个span标签。 |
//ul/span[position()>1] | 选择ul下面的span标签,从第二个开始选择 |
//li/span/a[text()='目录 '] | 选择所有li下的span标签,仅仅选择文本为 目录 的a标签 |
//ul/li[position()>5 and position()<13] | 选择ul下面的li标签,从第5个开始选择,第3个结束 |
4.3 lxml 模块
4.3.1 安装
pip install lxml
4.3.2 导入
导入lxml 的 etree 库
from lxml import etree
4.3.3 使用
1. 利用etree.HTML,将字符串转化为Element对象,Element对象具有xpath的方法,返回结果的列表,能够接受bytes类型的数据和str类型的数据
2. 把转化后的element对象转化为字符串,返回bytes类型结果
etree.tostring(element)
3.使用xpath 进行提取
html = etree.HTML(text)
ret_list = html.xpath("xpath字符串")
5. BeautifulSoup
Beautiful Soup 也是一个HTML/XML的解析器,主要的功能也是如何解析和提取 HTML/XML 数据。
5.1 Bs4 使用
5.1.1 下载导入
1. 下载
pip install bs4
2.导入
from bs4 import BeautifulSoup
5.1.2 lxml解析器
使用以下方式指定lxml解析器
soup = BeautifulSoup(html,“lxml”)
解析器 | 使用方法 | 优势 | 劣势 |
---|---|---|---|
Python标准库 | BeautifulSoup(markup,"html.parser") | Python 的内置标准库、执行速度适中 、文档容错能力强 | Python 2.7.3 or3.2.2) 前的版本中文容错能力差 |
LXML HTML 解析器 | BeautifulSoup(markup,"lxml") | 速度快、文档容错能力强 | 需要安装 C 语言库 |
LXML XML解析器 | BeautifulSoup(markup,"xml") | 速度快、唯一支持 XML 的解析器 | 需要安装 C 语言库 |
html5lib | BeautifulSoup(markup,"html5lib") | 最好的容错性、以浏览器的方式解析文档、生成 HTML5 格式的文档 | 速度慢、不依赖外部扩展 |
5.2 CSS 选择器
5.2.1 通过标签选择器查找
title = soup.select('title')
print(soup.select('a'))
print(soup.select('span'))
5.2.2 通过类选择器查找
data = soup.select('.divcenter')
# 类名中间带空格处理方式
class_data = soup.select('.adsbygoogle.allinone_good')
5.2.3 通过 id 选择器查找
idata = soup.select('#first')
5.2.4 层级选择器 查找
div_data = soup.select('div .navigat')
5.2.5 通过属性选择器查找
tr_list = soup.select('tr[align="center"]')
a_list = soup.select('a[class="navigat"]')
5.2.6 获取文本内容
titles = soup.select('title')
for title in titles:
print(title.get_text())
5.2.7 获取属性
a_href = soup.select('li a[class="blue"]')
for a in a_href:
print(a.get('href'))
5.2.8 伪类选择器
addrs = soup.select('tr td:nth-child(3)')
for addr in addrs:
print(addr.get_text())
5.3 find_all
find_all(name, attrs, recursive, text, **kwargs)
1) name 参数
- 传入字符串:搜索方法中传入一个字符串参数,查找与字符串完整匹配的内容。
span = soup.find_all('span')
返回文档中所有的span标签
- 传入正则表达式:通过正则表达式的 match() 来匹配内容。
import re
for tag in soup.find_all(re.compile("^b")):
print(tag.name)
返回b开头的标签
- 传入列表:与列表中任一元素匹配的内容返回。
data = soup.find_all(['a', 'span'])
返回a和span标签的任意一个标签
2) attrs参数
data = soup.find_all(attrs={'class':"blue"})
返回class类名为blue的标签
5.4 find
find的用法与find_all一样
5.4.1 区别
find: 返回 第一个符合匹配结果
find_all: 返回 所有匹配结果的列表