5.1.python第五章:数据提取与清洗策略

数据提取和清洗策略

正则表达式

正则表达式常用命令

常用命令含义
.除了\n\r的所有字符
\d数字
\D非数字
\w=[a-zA-Z0-9_]数字、字母、下划线
\W非数字字母和下划线
\s空格(包括制表符换页符)
[a-z]小写英文字母
[a-zA-Z0-9]大小写英文字母和数字
[123]数字123
[^123]不是数字123
*出现次数>=0
+出现次数>=1
{n}出现次数=n
{n,m}n<=出现次数<=m
^以开头
$以结尾
?关闭贪婪模式
‘()’用于获取括号内匹配成功的字符串

正则表达式案例

  1. 定义密码的正则表达式:英文字母开头,可以包括数字、大小写英文字母、下划线,6-16位

    password_pattern = ‘^ [a-zA-Z]{1}[a-zA-Z0-9_]{5-15} $’

  2. 匹配div标签,class=“class1”中的文本内容:<div class = “class1”> 要匹配的内容</div>

    div_pattern = '<div class = "class1">(.*)</div>'
    
  3. 匹配div标签,class=“class1”中的文本内容:<div><div class = “class1”> 要匹配的内容</div></div>

    div_pattern = '<div class = "class1">(.*)</div>'
    # 如果还是这么写的话,那么匹配到的将会是
    # 要匹配的内容</div>
    # 多了一个div标签是因为正则表达式正常是贪婪模式,会尽可能匹配多的内容
    # 因此我们需要关闭贪婪模式
    div_pattern = '<div class = "class1">(.*?)</div>'
    

re模块

re模块常用命令

命令含义
*search(···)在整个字符串中查找,返回第一个匹配的内容,如果找到返回match对象,如果没有返回None
*match(【正则表达式】,【被提取的字符串】)从头匹配,如果找到返回match对象,如果没有返回None
*findall(【正则表达式】,【被提取的字符串】)找到所有符合的,返回列表类型
finditer(···)在字符串中匹配
split(···)按照匹配的字符串分割
*sub(【正则】,【替换成的字符串】,【被匹配的字符串】)替换匹配的子字符串,返回替换后的字符串
group()结果转化为内容
groupdict()结果转化为字典
<body>
    <footer>
        <div>
            <div class="email">
                Email:kkk@qq.com
            </div>
            <div class="tel">
                手机号:400-4000-6666
            </div>
        </div>
    </footer>
</body>
import re

with open('index.html','r',encoding='utf-8')as f:
    html = f.read()
    print(html)
    # 2.将所有换行符替换成''
    html = re.sub('\n','',html)
    print(html)
    pattern_1 = '<div class="email">(.*?)</div>'
    ret_1 = re.findall(pattern_1,html)
    print(ret_1[0].strip())# 3. 消除首位空格和换行符
    # 返回结果是空列表,因为没有对\n换行符进行过滤
import re

with open('static/html/index.html','r',encoding='utf-8') as f:
    html = f.read()
    html = re.sub('\n', '', html)
    #print(html)
    section_pattern = '<section class="main_section">(.*?)</section>'
    # 将含有课程种类和课程名称的一大块提取出来
    section_s = re.findall(section_pattern,html)
    # print(section_s)
    # print(len(section_s))
    category_pattern = '<h1>(.*?)</h1>'
    # 课程种类的正则表达式
    course_pattern = '<span class="course_name">(.*?)</span>'
    # 课程名称的正则表达式
    data_s = []
    for section in section_s:
        category = re.findall(category_pattern,section)[0]
        course = re.findall(course_pattern,section)
        data_s.append(
            {
                'category':category,
                'course':course
             }
        )
    print(data_s)
    for data in data_s:
        print(data.get('category'))
        for course in data.get('course'):
            print('     ',course)

XPath

XPath即为XML路径语言,它是一种用来确定XML文档中某部分位置的语言

谷歌浏览器配置XPath插件

  1. 点击拓展程序
  2. 拖拽xpath—helper.crx到浏览器
  3. 出现安装包无效的问题:
    1、将crx结尾的扩展包的后缀名更改为rar格式的压缩包文件,直接确认
    2、将压缩包进行解压缩,然后将路径下的_metadata改为metadata
    3、进入Chrome浏览器的加载扩展程序界面,点击“加载已解压的扩展程序”,进入解压后的文件夹就可以直接安装了。

XPath常用语法

表达式描述
/根节点选取或下级
//任意节点,不考虑位置
.当前节点
当前节点的父节点
@选取属性
*匹配任何节点
[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()

在pycharm中引入lxml.etree 包标红解决办法:在file-setting-project-project interpreter 中点击右方加号install lxml

百度针对XPath爬虫的反爬策略和解决方式

反爬策略:将html代码注释,再在js中取消注释来反lxml爬虫,则用正则表达式进行爬取

 import lxml.etree as le

 with open('meiju1.html','r',encoding='utf-8') as f:
     # meiju2 有反爬,需要用正则表达式
     html = f.read()
     html_x = le.HTML(html)
     print(html_x)
     title_s = html_x.xpath('//div[contains(@class,"threadlist_title pull_left j_th_tit")]/a/text()')
     for title in title_s:
         print(title)

 import re

 with open('meiju2.html','r',encoding='utf-8') as f:
     html = f.read()
     html = re.sub('\n','',html)
     title_pattern = '<div class="threadlist_title pull_left j_th_tit ">.*?<a.*?>(.*?)</a>'
     title_s = re.findall(title_pattern,html)
     for title in title_s:
         print(title)

JsonPath使用案例

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))# str

# loads 用于把json对象转化成python对象
python_data2 = json.loads(json_data)
print(python_data2)
print(type(python_data2))# list

# dump 把python类型的数据转化成json类型的字符串,然后保存到本地
json.dump(python_data,open('json.txt','w'))

# load 用于读取本地的json数据,并转换成python对象
python_data3 = json.load(open('json.txt'))
print(python_data3)
print(type(python_data3))#list
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值