python爬虫之正则,xpath,bs4基础语法

1.正则表达式

1.1 正则表达式概述

正则表达式,又称规则表达式(Regular Expression,在代码中常简写为regex、regexp或RE),是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符"),是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个语法规则的字符串,通常被用来检索、替换那些符合某个模式(规则)的文本。
—正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。
—正则表达式使用单个字符串来描述、匹配一系列匹配某个语法规则的字符串

1.2 预定义字符集,数量词等

正则表达式预定义字符集有6个如下:
在这里插入图片描述在这里插入图片描述
数量词如下:
在这里插入图片描述在这里插入图片描述
一般字符如下:

字符含义
.匹配任意单个字符,不包括换行符\n
[…]字符集。对应字符集中的任意字符
\转义字符

边界匹配如下:

边界匹配含义
^匹配字符串开头
$匹配字符串结尾
\A仅匹配字符串开头
\Z仅匹配字符串结尾

1.3 search()函数

search()函数匹配并提取第一个符合规律的内容,返回的是一个正则表达式对象。

语法:re.search(pattern,string,flags=0)

(1)pattern为匹配的正则表达式。
(2)string为要匹配的字符串。
(3)flags为标志位,用于控制正则表达式的匹配方式,如是否区分大小写,多行匹配等。

例如:

import re
a='one111two222three333'
info=re.search('\d+',a)
print(info)  # 返回的是正则表达式对象
print(info.group())  # 用group方法获取信息

结果:
<re.Match object; span=(3, 6), match='111'>
111

1.4 sub()函数

sub()函数用于替换字符串中的匹配项。

语法:re.sub(pattern,repl,string,count=0,flags=0)

(1)pattern为匹配的正则表达式。
(2)repl为替换的字符串。
(3)string为要被查找替换的原始字符串。
(4)count为模式匹配后替换的最大次数,默认0表示替换所有的匹配。

例如:一个电话号码123-456-789,通过sub函数把中间的’-'去掉

import re
a='123-456-789'
a=re.sub('\D','',a)
print(a)

结果:
123456789

1.5 match()函数

match()函判从搜索文本的开始位置查找是否是需要的数据,注意是开始位置,如果匹配到了正则表达式样式,就返回一个相应的匹配对象。

语法:re.match(pattern, string, flags=0)

(1)pattern数是正则表达式,如果匹配成功,则返回一个match对象,否则返回一个None
(2)string表示要匹配的字符串
(3)flags是标致位用于控制正则表达式的匹配方式 如: 是否区分大小写,多行匹配等等

例如:

import re
a='1a3-456-789'
if re.match('^[^\d]',a):
    print('第一个是数字')
else:
    print('第一个不是数字')

结果:
第一个不是数字

1.6 findall()函数

findall()函数匹配所有符合规律的内容,并以列表的形式返回结果。

语法:re.findall(pattern, string, flags=0)

例如:

import re
a='one111two222three333'
info=re.findall('\d+',a)
print(info)  #['111', '222', '333']

str='123abc321'
data_str=re.findall('123(...)321',str)  #提取abc
print(data_str)  #['abc']

str2='111a222 111A222 1119222 111aa222 1113222 111afaf222'
data=re.findall('111(\D{2,4})222',str2)  # {2,4}表示2-4次
print(data)  # ['aa', 'afaf']

1.7 贪婪与非贪婪模式

在重复匹配时,正则表达式默认总是尽可能多的匹配,这被称为贪婪模式。例如,针对文本dxxxdxxxd,表达式(d)(\w+)(d)中的\w+将匹配第一个d和最后一个d之间的所有字符xxxdxxx。可见,\w+在匹配的时候,总是尽可能多的匹配符合它规则的字符。同理,带有?、*和{m,n}的重复匹配表达式都是尽可能地多匹配。

例如:

str='1aoao1o2o1nzn1afa'
data=re.findall('1(.*)1',str)  # .*贪婪匹配
print(data)  # ['aoao1o2o1nzn']
data1=re.findall('1(.*?)1',str) # 加上?变成非贪婪匹配  
print(data1)  # ['aoao', 'nzn']

2.bs4

2.1 bs4概述

简单来说,Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据。官方解释如下:

Beautiful Soup提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。
它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单, 所以不需要多少代码就可以写出一个完整的应用程序。

Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库。它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式。BeautifulSoup会帮节省数小时甚至数天的工作时间。

2.1 find()方法与findall()方法

find()方法返回搜索到的第一条数据。
find_all()方法以列表形式返回所有的搜索到的标签数据。
例如:

html = """
<table class="tablelist" cellpadding="0" cellspacing="0">
    <tbody>
        <tr class="h">
            <td class="l" width="374">职位名称</td>
            <td>职位类别</td>
            <td>人数</td>
            <td>地点</td>
            <td>发布时间</td>
        </tr>
        <tr class="even">
            <td class="l square"><a target="_blank" href="position_detail.php?id=33824&keywords=python&tid=87&lid=2218">22989-金融云区块链高级研发工程师(深圳)</a></td>
            <td>技术类</td>
            <td>1</td>
            <td>深圳</td>
            <td>2017-11-25</td>
        </tr>
        <tr class="odd">
            <td class="l square"><a target="_blank" href="position_detail.php?id=29938&keywords=python&tid=87&lid=2218">22989-金融云高级后台开发</a></td>
            <td>技术类</td>
            <td>2</td>
            <td>深圳</td>
            <td>2017-11-25</td>
        </tr>
        <tr class="even">
            <td class="l square"><a target="_blank" href="position_detail.php?id=31236&keywords=python&tid=87&lid=2218">SNG16-腾讯音乐运营开发工程师(深圳)</a></td>
            <td>技术类</td>
            <td>2</td>
            <td>深圳</td>
            <td>2017-11-25</td>
        </tr>
        <tr class="odd">
            <td class="l square"><a target="_blank" href="position_detail.php?id=31235&keywords=python&tid=87&lid=2218">SNG16-腾讯音乐业务运维工程师(深圳)</a></td>
            <td>技术类</td>
            <td>1</td>
            <td>深圳</td>
            <td>2017-11-25</td>
        </tr>
        <tr class="even">
            <td class="l square"><a target="_blank" href="position_detail.php?id=34531&keywords=python&tid=87&lid=2218">TEG03-高级研发工程师(深圳)</a></td>
            <td>技术类</td>
            <td>1</td>
            <td>深圳</td>
            <td>2017-11-24</td>
        </tr>
        <tr class="odd">
            <td class="l square"><a target="_blank" href="position_detail.php?id=34532&keywords=python&tid=87&lid=2218">TEG03-高级图像算法研发工程师(深圳)</a></td>
            <td>技术类</td>
            <td>1</td>
            <td>深圳</td>
            <td>2017-11-24</td>
        </tr>
        <tr class="even">
            <td class="l square"><a target="_blank" href="position_detail.php?id=31648&keywords=python&tid=87&lid=2218">TEG11-高级AI开发工程师(深圳)</a></td>
            <td>技术类</td>
            <td>4</td>
            <td>深圳</td>
            <td>2017-11-24</td>
        </tr>
        <tr class="odd">
            <td class="l square"><a target="_blank" href="position_detail.php?id=32218&keywords=python&tid=87&lid=2218">15851-后台开发工程师</a></td>
            <td>技术类</td>
            <td>1</td>
            <td>深圳</td>
            <td>2017-11-24</td>
        </tr>
        <tr class="even">
            <td class="l square"><a target="_blank" href="position_detail.php?id=32217&keywords=python&tid=87&lid=2218">15851-后台开发工程师</a></td>
            <td>技术类</td>
            <td>1</td>
            <td>深圳</td>
            <td>2017-11-24</td>
        </tr>
        <tr class="odd">
            <td class="l square"><a id="test" class="test" target='_blank' href="position_detail.php?id=34511&keywords=python&tid=87&lid=2218">SNG11-高级业务运维工程师(深圳)</a></td>
            <td>技术类</td>
            <td>1</td>
            <td>深圳</td>
            <td>2017-11-24</td>
        </tr>
    </tbody>
</table>
"""

代码:

# 1 获取所有的tr标签
trs = soup.find_all("tr")  
for tr in trs:
    print(tr)
    print("*" * 150)


# 2 获取第二个tr标签
tr = soup.find_all("tr")[1]
print(tr)


# 3 获取获取所有的class =even的tr标签
trs = soup.find_all("tr", class_="even")  # 但这里如果直接用class不行 class是作为我们的关键字
# trs = soup.find_all("tr", attrs={"class": "even"})  这两种方式都可
for tr in trs:
    print(tr)
    print("*" * 150)


# 4 获取所有的a标签的href属性
a_li = soup.find_all("a")
for a in a_li:
    href = a.get("href")
    print(href)


# 5 获取所有的岗位信息。
trs = soup.find_all("tr")[1:]
for tr in trs:
    tds = tr.find_all("td")
    # print(tds)
    job_name = tds[0].string
    print(job_name)

3.xpath

3.1 xpath概述

XPath(XML Path Language)是一种XML的查询语言,他能在XML树状结构中寻找节点。XPath 用于在 XML 文档中通过元素和属性进行导航
xml是一种标记语法的文本格式,xpath可以方便的定位xml中的元素和其中的属性值。lxml是python中的一个第三方模块,它包含了将html文本转成xml对象,和对对象执行xpath的功能。

3.2 基本定位语法

节点选择

表达式描述
/从根节点选取
//从任意节点开始选取
.选取当前节点
. .选取当前节点的父节点
@选取属性或者根据属性选取

节点选择实例

路径表达式结果
/user_data选取根元素user_data
user_data/user选取属于user_data的子元素的所有user元素
//user选取所有user子元素,而不管它们在文档的位置
//@attribute选取名为attribute的所有属性

谓语

路径表达式结果
/user_date/user[1]选取属于user_data子元素的第一个user元素
//li[@attribute]选取所有拥有名为attribute属性的li元素
//li[@attribute=“red”]选取所有li元素,且这些元素拥有值为red的attribute属性

3.3 实战

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="search" id="form" method="post">
  <span class="bg">
    <span class="soutu">搜索</span>
  </span>
  <span class="soutu">
    <input type="text" name="key" id="su">
  </span>
  <div></div>
</form>
</body>
</html>

使用谓语定位,谓语是 Xpath 中用于描述元素位置。主要有数字下标、最后一个子元素last()、元素下标函数position()。注意点:Xpath 中的下标从 1 开始。

1、使用下标的方式,从form找到input:
//form[@id="form"]/span[2]/input

2、查找最后一个子元素,选取form下的最后一个span:
//form[@id="form"]/span[last()]

3、查找倒数第几个子元素,选取 form下的倒数第二个span:
//form[@id="form"]/span[last()-1]

4、使用 position() 函数,选取 from 下第二个span:
//form[@id="form"]/span[position()=2]

5、使用 position() 函数,选取下标大于 2 的span:
//form[@id="form"]/span[position()>2]
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值