Fork me on GitHub

Python_Spider_Regex

正则表达式 Regex

  • 1.正则表达式定义:正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符和这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑
  • 2.需要取出来的就(.*?)
  • 3.(. ) 贪婪模式———将标签内所有复合内容提取
    (.
    ?) 非常模式——只提取有用部分
字符 作用
. 匹配所有英文字符
a[bcd]e 匹配字符集 匹配 a()e ()内bcd任意一个都可匹配
\d 匹配数字 “\D”:匹配除数字外
\s 匹配空格,换行符等 “\S”:匹配非空格,换行符
\w 匹配数字和字母 “\W”: 匹配非数字和字母
^abc 匹配开头
abc$ 匹配结尾
(”abc”,”abcABC”,re.I) 不区分大小写的匹配
(”abc”,”abc\nABC”,re.S) 避免换行符等干扰提取内容
ab? 在a后面匹配一个或0个b
ab+ 在a后面匹配至少一个b
ab* 在a后面匹配至少0个b

当既要不分大小写,又要去除换行等影响,则(或运算)

| re.S)```
1
2
3
4
5
6
7
8
9
10
11
12

---
[TOC]
### 匹配模式
```Python
#匹配模式有:
1)re.I(re.IGNORECASE): 忽略大小写
2)re.M(MULTILINE): 多行模式,改变’^’和’$’的行为
3)re.S(DOTALL): 点任意匹配模式,改变’.’的行为,可匹配换行符
4)re.L(LOCALE): 使预定字符类 \w \W \b \B \s \S 取决于当前区域设定
5)re.U(UNICODE): 使预定字符类 \w \W \b \B \s \S \d \D 取决于unicode定义的字符属性
6)re.X(VERBOSE): 详细模式。这个模式下正则表达式可以是多行,忽略空白字符,并可以加入注释

1
2
3
s= "<div>hello\nworld</div>"
#去除\n的影响
m = re.findall(r"<div>(.*)</div>",s,re.S)


re –方法

1、findall & find

1
2
3
4
5
6
7
8
import re
# re.findall(pattern, string)
# pattern 表示我们希望寻找的子字符串
# string 表示我们要在其中查找的主字符串

content = re.findall(r'代码内容 .*?代码内容',url.text,re.S)
#若在代码内容中有特殊字符,需要被转义,例如r'<script\(\)>;</script>'
#使用re.S的作用为在代码中有许多回车与换行,若不加,则可能匹配不到内容

注意:至少两个参数,一个为正则表达式,另一个为源代码

1
2
3
4
5
6
content = requests.get(url).content.decode('gb2312')
#转义双引号
start = content.find('<map name=\"map_86\" id=\"map_86\"')
end = content.find('</map>')
content = content[start:end + len('</map>')].strip()
print (content)

re.search()
: 匹配的是一个模式在一个字符串中的第一个实例,然后以 re 匹配对象的形式返回它。

因为 re.search() 返回的是一个 re 匹配对象,所以我们不能直接通过 print 展示其中的内容。
我们必须首先为其应用group() 函数。

group()
: 函数的作用是将匹配对象转换成字符串。re.search().group()

group(0)则是整个匹配的内容,返回一个实体对象
group(1)则是匹配第一个括号里面的内容,取出括号里匹配的实体对象
group(2)则是匹配第二个括号里面的内容,取出括号里匹配的实体对象
group(0,1,2)则返回一个实体对象的元组

3、re.split()

分割字符

1
2
3
4
5
6
7
8
import re
#不保留匹配项
m = re.split('\d+' , '123abc321cba')
print m
print "\n"
#保留匹配项,加()
m = re.split('(\d+)' , '123abc321cba')
print m

4、re.sub()

re.sub()
: 是另一个很好用的 re 函数。顾名思义,它的功能是替换一个字符串的一部分。

有三个参数
第一个是所要替换的子字符串,第二个是用来替换前者的字符串,第三个是主字符串本身

1
2
3
4
5
sender = re.search("From:.*", fh)
address = sender.group()
email = re.sub("From", "Email", address)
print(address)
print(email)


改进

1
2
3
4
5
6
7
8
9
#小操作

#1.以列表形式储存数据
output = []
#2.去除空格
output.append(content[0].replace("\n",""))
#3.设置爬虫休眠时间,防止爬取速度过快而被封
import time
time.sleep(1)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#如果是多次调用某个正则,则最好先编译后使用
p = re.compile("^abc")
m1 = re.findall("abc\nabc")
m2 = re.findall("abced\nsdf")
m3 = re.findall("dfsfd\nabcdf")

#函数re.compile将正则表达式(以字符串书写的)转换为模式对象,可以实现更加有效的匹配。例子:
import re
text = "JGood is a handsome boy, he is cool, clever, and so on..."
re.findall(r'\w*oo\w*', text) #查找所有包含'oo'的单词

#使用compile函数:
#导入re模块:
import re
text = “JGood is a handsome boy, he is cool, clever, and so on…”
regex = re.compile(r‘’\w*oo\w*’)
print regex.findall(text) #查找所有包含’oo’的单词

内容清洗(去空白字符等)

1
2
3
4
5
6
7
8
9
import re
import requests
import html
#将编译后的内容去除转义符,即清洗内容
url = "www..."
response = requests.get(url)
pattern = re.compile("div...",re.S)
body = html.unescape(response.text).replace("<br/>","\n")
m = pattern.findall(body)

详细概念

*匹配 0 个或更多个其左侧的模式的实例。也就是说它会查找重复的模式。
当我们查找重复模式时,我们说我们的搜索是贪婪匹配
如果我们没有查找重复模式,我们可以说我们的搜索是非贪婪匹配懒惰匹配

喜欢的可以对我打赏了哟~