表达式 | 说明 |
---|---|
. | 除了\n和\r的所有字符 |
\d | 数字 |
\D | 非数字 |
\w | 数字字母和下划线 |
\W | 非数字字母和下划线 |
\s | 空格(包括制表符、换页符) |
------------------------------- | ------------------------------------- |
[a-z] | 小写应为字母 |
[a-zA-Z0-9] | 大小写英文字母与数字 |
[123] | 数字123 |
[^ 123] | 不是数字123 |
* | 出现次数>=0 |
+ | 出现次数>=1 |
{n} | 出现次数=n |
{n,m} | m>=出现次数>=n |
^ | 以开头 |
$ | 以结尾 |
? | 关闭贪婪模式 |
() | 用于获取括号内匹配成功的字符串 |
定义密码的正则表达式:
规则:英文字母开头,可以包括数字、大小写英文字母、下划线,6-16位
password_pattern = '^ [a-zA-Z]{1}[a-zA-Z0-9_]{5-15}$'
#等价于
password_pattern = '^ [a-zA-Z][a-zA-Z0-9_]{5-15}$'
#匹配div标签,class='class1'中的文本内容:
<div class='class1'>要匹配的内容</div>
div_pattern = '(.*)'
#匹配的结果为:
<div class='class1'>**要匹配的内容**</div>
#当匹配div标签,class='class1'中的文本内容为:
<div><div class='class1'>要匹配的内容</div></div>
div_pattern = '(.*)'
#匹配的结果为:
<div><div class='class1'>**要匹配的内容</div>**</div>
#正则表达式默认开启贪婪模式,默认匹配尽可能多的字符串
#取消贪婪模式:
div_pattern = '(.*?)'
#匹配结果为:
<div><div class='class1'>**要匹配的内容**</div></div>
#导入re模块
import re
#findall方法
ret = re.findall(【正则表达式】,【被提取的字符串】)
#注:返回的类型是列表,如果未匹配成功返回一个空列表
import re
#match方法
ret = re.match(【正则表达式】,【被匹配的字符串】)
#注:匹配密码
# 如果匹配成功,返回对象
# 如果匹配不成功,返回None
import re
# sub方法
ret = re.sub(【正则表达式】,【替换成的字符串】,【被替换的字符串】)
import re
with open('index.html','r',encoding='utf-8') as f:
html = f.read()
#替换文件中换行符
html = re.sub('\n','',html)
print(html)
#提取数据
pattern_1 ='(.*?)'
ret_1 = re.findall(pattern_1,html)
#去掉空格
print(ret_1[0].strip())
#匹配密码
password_pattern = r'^[a-zA-Z][a-zA-Z0-9_]{5,15}$'
pass1 = '1234567'
pass2 = 'k123456'
pass3 = 'k123'
print(re.match(password_pattern,pass1))
print(re.match(password_pattern,pass2))
print(re.match(password_pattern,pass3))
对下面HTML文件进行提取
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CSDN微课商城</title>
<link rel="stylesheet" href="../css/main.css">
<script type="text/javascript" src="../js/main.js"></script>
</head>
<body>
<div id="register" hidden="hidden">
<h2 class="form_p">注册</h2>
<p id="register_message">
<!--信息有误-->
</p>
<form action="#" method="post" id="register_form">
<input id="register_account" type="text" name="account" placeholder="账号(数字、英文、下换线,8-16位)"><br/>
<input id="register_password" type="password" name="password" placeholder="密码(数字、英文、下换线,6-16位)"><br/>
<!--<input type="password" name="repassword" placeholder="确认密码"><br/>-->
<input id="register_submit" type="submit" value="注册">
</form>
</div>
<div id="login" hidden="hidden">
<h2 class="form_p">登录</h2>
<p id="login_message">
<!--信息有误-->
</p>
<form action="#" method="post" id="login_form">
<input id="login_account" type="text" name="account" placeholder="账号"><br>
<input id="login_password" type="password" name="password" placeholder="密码"><br>
<input id="login_submit" type="submit" value="登录">
</form>
</div>
<header>
<span class="title"> <a href="index.html">CSDN微课商城</a> </span>
<span>
<form action="#" class="search_form">
<input type="text" name="course" placeholder="按课程名称搜索">
<input type="submit" value="搜索">
</form>
</span>
<span class="user">
<a href="javascript:show('login')">登录</a>/
<a href="javascript:show('register')">注册</a>
<!-- 已经登录显示的内容 -->
你好:
<a href="user.html">用户1</a>
<a href="#">注销</a>
</span>
</header>
<article>
<section class="nav_section"><img src="../img/csdn_static/2.png" alt="" width="100%"></section>
<section class="main_section"><h1>第一章 路由与模板</h1>
<figure><a href="course.html"> <img src="../img/course/course.png">
<figcaption><span class="course_name">Web原理与框架简介</span><span class="price">¥75</span></figcaption>
</a></figure>
<figure><a href="course.html"> <img src="../img/course/course.png">
<figcaption><span class="course_name">Django环境搭建与入门案例</span><span class="price">¥153</span></figcaption>
</a></figure>
<figure><a href="course.html"> <img src="../img/course/course.png">
<figcaption><span class="course_name">基本路由映射与命名空间</span><span class="price">¥154</span></figcaption>
</a></figure>
<figure><a href="course.html"> <img src="../img/course/course.png">
<figcaption><span class="course_name">正则路由映射参数的传递与接收</span><span class="price">¥177</span></figcaption>
</a></figure>
<figure><a href="course.html"> <img src="../img/course/course.png">
<figcaption><span class="course_name">反向解析处理器</span><span class="price">¥161</span></figcaption>
</a></figure>
<figure><a href="course.html"> <img src="../img/course/course.png">
<figcaption><span class="course_name">Request对象与Response对象</span><span class="price">¥44</span></figcaption>
</a></figure>
<figure><a href="course.html"> <img src="../img/course/course.png">
<figcaption><span class="course_name">上下文与模板调用</span><span class="price">¥97</span></figcaption>
</a></figure>
<figure><a href="course.html"> <img src="../img/course/course.png">
<figcaption><span class="course_name">模板层基础语法</span><span class="price">¥105</span></figcaption>
</a></figure>
<figure><a href="course.html"> <img src="../img/course/course.png">
<figcaption><span class="course_name">模板过滤器</span><span class="price">¥133</span></figcaption>
</a></figure>
</section>
<section class="main_section"><h1>第二章 模型类实现</h1>
<figure><a href="course.html"> <img src="../img/course/course.png">
<figcaption><span class="course_name">ORM原理与数据库配置</span><span class="price">¥143</span></figcaption>
</a></figure>
<figure><a href="course.html"> <img src="../img/course/course.png">
<figcaption><span class="course_name">表与字段的定义和常用字段约束</span><span class="price">¥118</span></figcaption>
</a></figure>
<figure><a href="course.html"> <img src="../img/course/course.png">
<figcaption><span class="course_name">数据迁移与维护</span><span class="price">¥57</span></figcaption>
</a></figure>
<figure><a href="course.html"> <img src="../img/course/course.png">
<figcaption><span class="course_name">模型类的增删改</span><span class="price">¥45</span></figcaption>
</a></figure>
<figure><a href="course.html"> <img src="../img/course/course.png">
<figcaption><span class="course_name">模型类的查询方法</span><span class="price">¥187</span></figcaption>
</a></figure>
<figure><a href="course.html"> <img src="../img/course/course.png">
<figcaption><span class="course_name">QuerySet详解</span><span class="price">¥197</span></figcaption>
</a></figure>
</section>
</article>
<footer>
<div id="footer_div1">
<p><a href="#">关于我们</a>| <a href="#">招聘</a>| <a href="#">广告服务</a>| <a href="#">网站地图</a></p>
<p><a href="#">QQ客服</a>| <a href="#">kefu@csdn.ent</a>| <a href="#">客服论坛</a>| <a href="#">400-660-0108</a>| <a
href="#">工作时间:8:30-22:00</a></p>
<p> 百度提供站内搜索 北ICP备19004658 </p>
<p> ©1999-2019 北京创新乐知网络技术有限公司 </p>
<p> 版权申诉 家长监护 经营性网站备案信息 网络110报警服务 中国互联网举报中心 北京互联网违法和不良信息举报中心 </p>
</div>
<div id="footer_div2">
<figure><img src="../img/csdn_static/二维码1.png">
<figcaption>CSDN咨询</figcaption>
</figure>
<figure><img src="../img/csdn_static/二维码1.png">
<figcaption>CSDN学院</figcaption>
</figure>
<figure><img src="../img/csdn_static/二维码1.png">
<figcaption>CSDN企业招聘</figcaption>
</figure>
</div>
</footer>
</body>
</html>
提取过程
import re
with open('static/html/index.html','r',encoding='utf-8') as f:
#去掉换行符
html =re.sub('\n','',f.read())
#print(html)
#提取课程种类
#建立正则表达式
section_pattern = '(.*?) '
section_s = re.findall(section_pattern,html)
print(section_s)
print(len(section_s))
#建立课程种类的正则表达式
category_pattern = '(.*?)
'
#建立课程名称的正则表达式
course_pattern ='(.*?)'
#建立一个列表
data_s=[]
#遍历section_s
for section in section_s:
#在section中取到课程种类对象
category = re.findall(category_pattern,section)
#取到课程种类对象列表中的课程种类信息
#print(category[0])
course_s = re.findall(course_pattern,section)
data_s.append(
{
'category':category,
'course_s':course_s
}
)
print(data_s)
for data in data_s:
print(data.get('category'))
for course in course_s:
print(' ',course)
提取结果
C:\Users\Lenovo\AppData\Local\Programs\Python\Python38\python.exe C:/Users/Lenovo/PycharmProjects/提取商城分类结构/re_index.py
['第一章 路由与模板
', '第二章 模型类实现
']
2
[{'category': ['第一章 路由与模板'], 'course_s': ['Web原理与框架简介', 'Django环境搭建与入门案例', '基本路由映射与命名空间', '正则路由映射参数的传递与接收', '反向解析处理器', 'Request对象与Response对象', '上下文与模板调用', '模板层基础语法', '模板过滤器']}, {'category': ['第二章 模型类实现'], 'course_s': ['ORM原理与数据库配置', '表与字段的定义和常用字段约束', '数据迁移与维护', '模型类的增删改', '模型类的查询方法', 'QuerySet详解']}]
['第一章 路由与模板']
ORM原理与数据库配置
表与字段的定义和常用字段约束
数据迁移与维护
模型类的增删改
模型类的查询方法
QuerySet详解
['第二章 模型类实现']
ORM原理与数据库配置
表与字段的定义和常用字段约束
数据迁移与维护
模型类的增删改
模型类的查询方法
QuerySet详解
表达式 | 描述 |
---|---|
/ | 根节点选取或下级 |
// | 任意节点,不考虑位置 |
. | 当前节点 |
… | 当前节点的父节点 |
@ | 选取属性 |
* | 匹配任何节点 |
【nodename】 | 根据节点筛选 |
contains(@属性,‘包含的内容’) | 模糊查询 |
text() | 文本内容 |
注:XPath中的索引从1开始
代码实际应用
一级分类: //h3[@class="classify_c_h3"]/a/text()
二级分类: //div[@class="classify_list"]/span/a/text()
//div[contains(@class,"classify_list")]/span/a/text()
实战数据提取CSND学院主页数据
截取操作代码
import lxml.etree as le
with open('edu.html','r',encoding='utf-8') as f:
html = f.read()
html_x = le.HTML(html)
#print(html_x)
div_x_s = html_x.xpath('//div[@class="classify_cList"]')
#print(div_x_s)
data_s = []
for div_x in div_x_s:
category1=div_x.xpath('./h3/a/text()')[0]
#print(category1)
category2_s = div_x.xpath('./div/span/a/text()')
#print(category2_s)
data_s.append(
dict(
category1=category1,
category2_s=category2_s
)
)
#print(data_s)
for data in data_s:
print(data.get('category1'))
for category2 in data.get('category2_s'):
print(' ',category2)
import lxml.etree as le
with open('meiju1.html','r',encoding='utf-8') as f:
html = f.read()
html_x = le.HTML(html)
title_s = html_x.xpath('//div[contains(@class,"threadlist_title pull_left j_th_tit")]/a/text()')
print(title_s)
for title in title_s:
print(title)
import lxml.etree as le
import re
with open('meiju2.html','r',encoding='utf-8') as f:
html = re.sub('\n','',f.read())
title_pattern = '.*?(.*?)'
title_s = re.findall(title_pattern,html)
for title in title_s:
print(title)
JsonPath使用案例
dumps和loads用法
import json
python_data = [
{
'username':'name1',
'vip':True
},
{
'username':None,
'vip':False,
}
]
#dumps 用于把Python对象转换成Json对象
json_data = json.dumps(python_data)
print(json_data)
print(type(json_data))
#loads 用于把Json对象转换成Python对象
python_data2 = json.loads(json_data)
print(python_data2)
print(type(python_data2))
dump和load用法
import json
python_data = [
{
'username':'name1',
'vip':True
},
{
'username':None,
'vip':False,
}
]
#dump 用于把Python类型的数据转换成Json类型的字符串,保存到本地
json.dump(python_data,open('json.txt','w'))
#load 用于读取本地json数据本转换成python对象
python_data2=json.load(open('json.txt'))
print(python_data2)