爬虫Python

(十)学习笔记:python中的正则re模块和url处理模块总结

2018-04-11  本文已影响33人  fanhang64

正则

正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配,提供了一种字符串的匹配模式(pattern)
常用的元字符

1.  []   # 包含,默认是一个字符长度
    [a]  # 匹配a字母
    [abc]  # 匹配a或b或c中的任意一个
    [a-z]  # 匹配a-z中的任意一个
    [A-Z]  # 匹配A-Z中的任意一个
    [a-zA-Z]  # 匹配任意一个字母
    [0-9]  # 匹配数字
2. ^ 以..开头
    ^a  # 匹配以a作为开头的一串字符
    ^abc  # 匹配以abc作为开头的一串字符
    ^[abc]    # 匹配a或b或c开头的一串字符
    [^abc]  # 匹配除去a或b或c以外的
    [^a-zA-Z]  # 匹配a-z或A-Z以外的字符
 3.  $  以..结尾
     ^[1][3-8][0-9]{9}$  # 匹配手机号, 以1作为开头 第二位是3-8, 后几位是0-9
     ^[1][345678][0-9]{9}$  # 匹配手机号, 同上
4.  {m}  表示匹配前面表达式m次
    abc{2}  # 匹配ab和c两次
    1[a-z]{2}  # 匹配1和两个小写字母
5.  {m,n}  表示匹配前面的表达从m到n次
    [1-9][0-9]{4,10}     # 匹配第一位是1-9, 4到10位的数字0-9  
6.  {m,}  匹配前面的表达式至少m次
7. ?  表示前面的表达式可有可无
    [1-9][0-9]?   # 匹配数字1-99(后面的一位0-9可有可无)
8.  .   匹配除了换行符\n以外的任意字符
    .{2}   # 匹配除了换行符以外的任意两个字符。
9.  * 匹配起那么的表达式 0次到多次
    .*  # 匹配除了换行符以外的任意字符任意次--贪婪模式 
    .{0,}  # 同上
    .*?  # 匹配除了换行符以外的任意字符任意次--拒绝贪婪模式 
10. + 表示匹配前面的表达式1次到多次
    .+  # 匹配除了换行符以外的任意字符至少一次-- 贪婪模式 
    .{1,}  # 同上
    .+?  # 匹配除了换行符以外的任意字符至少一次--拒绝贪婪模式 
11.  ()  # 代表一个临时区域单元, 表达式定义为组;2.匹配括号内容并获取这一匹配。
12. |  或
    a|b  # 匹配a或b
    ab(c|d)  # 匹配ab与c或d其中一个

正则在python中的修正符

re.I  # 匹配不区分大小写, 还可以使用全称的re.IGNORECASE。
re.M  # 将要匹配的字符串视为多行,可以匹配每一行, 还可以使用全称的re.MULTILINE
re.S  # 将要匹配的字符串视为单行,并把换行符作为一个普通字符匹配,还可以使用全称的re.DOTALL

# 可以使用或运算符|同时设置多个修正符。

特殊意义的字符

\d  等同于[0-9]   # 匹配一位数字
\D  等同于[^0-9]  # 匹配除了数字以外的一个字符
\w  等同于[a-zA-Z0-9_ ]  # 匹配数字字母下划线的一个字符
\W  等同于[^a-zA-Z0-9_ ]  # 匹配除了字母数字下划线的其他字符
\s    等同于[\n\r\t] # 匹配空白字符 包括空格、制表符、换页符等等
\S   # 匹配非空白字符

正则常用的函数

导入模块

import re

(1) re.findall(pattern, string, flags)

匹配所有内容,李列表的形式返回, 当匹配失败时候返回空列表
参数1:正则的匹配规则
参数2:要匹配的字符串
参数3:修正符

实例:

myStr = """
<a href="http://www.baidu.com">百*</a>    # 给每一行进行编号1
<a href="http://www.taobao.com">淘*1</a>  # 2 
<a href="www.taobao.com">淘*2</a>         #  3
<A href="http://www.id97.com">电影网站</>   # 4
<a href="http://www.jd.com">*东                 # 5
</a>
"""
dataList = re.findall('<a href=".*?">.*?</a>',myStr)  #  匹配1,2,3. 返回列表
dataList = re.findall('<a href=".*?">.*?</a>', myStr, re.I)  # 匹配编号1234,不区分大小写 
dataList = re.findall('<a href=".*?">.*?</a>',myStr,re.S|re.I)  # 匹配12345   
print(dataList)  

(2) re.match(pattern, string, flags)

从开始位置匹配,只匹配一次, 匹配成功返回对象,匹配失败返回None
参数同上
实例:

ret = re.match("[a]","1a")
print(ret)  # None  从开始第一个位置处匹配
ret = re.match("[a-zA-Z]{2,3}","Aaaaaa")
print(ret)   # 返回对象 <_sre.SRE_Match object; span=(0, 3), match='Aaa'>, 匹配了三次
# 使用返回的对象的group()方法获取匹配的结果
print(ret.group())  # Aaa

(3) re.search(pattern, string, flags)

匹配一次, 匹配成功返回匹配的对象,匹配失败返回None。与re.match()区别是就是可以从任意位置匹配
实例:

ret = re.search("[a]","1a")
print(ret)  #   从开始第二个位置处匹配 <_sre.SRE_Match object; span=(1, 2), match='a'>
print(ret.group())  # 打印 a

(4) re.sub(pattern, repl,count, flags)/re.subn()

使用正则表达式替换, 返回替换后的结果
re.subn()可以返回替换后的结果和次数
实例:

myStr = "<b>我是b</b><i>我是i</i><strong>我是strong</strong>"
# 将b换成em 即<em>第三方</em>
data = re.sub("<b>(.*?)</b>", "<em>我是em</em>", myStr)
print(data)   #  <em>我是em</em><i>我是i</i><strong>我是strong</strong>
# 将所有的标签名换成em,不改变标签内的内容
data  = re.sub("<b>(.*?)</b><i>(.*?)</i><strong>(.*?)</strong>", "<em>\\1</em><em>\\2</em><em>\\3</em>",myStr)
print(data)  # 其中\1是取第一个(.*?)获取的内容, \2是第二个(.*?)的内容,...。<em>我是b</em><em>我是i</em><em>加粗strong</em> 
# 将1970/01/02变为01月02日1970年(考察分组,内容的获取)
myData = "1970/01/02"
ret = re.sub("(\d+)/(\d+)/(\d+)", "\\2月\\3日\\1年", myData)
print(ret)  #  01月02日1970年

(5)re.split(pattern,string,maxsplit,flags)

正则的拆分, 将字符串拆分成列表
参数:
maxsplit: 最大的拆分次数
实例:

data = "1jjj1h$hhh1hjj&j1"
print(re.split("\W",data))  #  ['1jjj1h', 'hhh1hjj', 'j1']   ---使用除了字母数字下划线以外的字母进行拆分 
print(re.split("\d",data))  # ['', 'jjj', 'h$hhh', 'hjj&j', ''] ---使用一位数字进行拆分
print(re.split("\d",data,1))  # ['', 'jjj1h$hhh1hjj&j1'] ---使用一位数字进行拆分,拆分一次

(6)re.finditer(pattern,string,maxsplit,flags)

匹配所有, 以迭代器的形式返回结果
实例:

myStr = "abcDMdefg23456uuii"
reIter = re.finditer("[a-z]",myStr)    # 匹配的结果应该是abcdefguuii, 但是使用迭代器返回了
print(reIter)  #  <callable_iterator object at 0x...>
print(next(reIter))  # 调用next()输出 <_sre.SRE_Match object; span=(0, 1), match='a'>
print(next(reIter).group())  # a  ---进行取值

(7) re.compile(pattern, flags)

先使用compile()函数, 将正则表达式编译为Pattern实例, 然后使用Pattern实例处理文本并获得匹配结果, 执行效率高 将正则和字符串分开
实例:

myStr = "abcDMdefg23456uuii"
pattern = re.compile("[a-z]")
ret = pattern.findall(myStr)  # 其他的方法(match,sub..)都可以使用
print(ret)  # ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'u', 'u', 'i', 'i']

URL处理模块

导包

import urllib.request

(1) urlopen(url, timeout) 打开连接地址

timeout: 设置超时时间
实例:

import urllib.request
url = "http://bbs.tianya.cn/m/post-140-393974-6.shtml"
response = urllib.request.urlopen(url,)
print(response)  # HTTPResponse object
print(response.read())  # 打印响应的内容,但是返回的是字节形式的内容,需要根据网页head设置的编码进行解码
print(response.read().decode('utf-8'))
print(response.readlines())  # 读取每一行 以列表的形式返回
print(response.code)  # 返回状态码
print(response.geturl())  # 获取当前访问的地址

(2) url地址编码

实例:

url = " https://www.baidu.com/s?word=美女&tn=site888_3_pg&lm=-1&ssl_s=1&ssl_c=ssl1_160e40bb10d"
ret = urllib.request.quote(url)  
print(ret)  # 对url地址进行url编码 https%3A//www.baidu.com/s%3Fword%3D%E7%BE%8E%E5%A5%B3%26tn%3Dsite888_3_pg%26lm%3D-1%26ssl_s%3D1%26ssl_c%3Dssl1_160e40bb10d
print(urllib.request.unquote(ret))  # 进行url解码  https://www.baidu.com/s?word=美女&tn=site888_3_pg&lm=-1&ssl_s=1&ssl_c=ssl1_160e40bb10d

(3) 添加用户代理UserAgent(在后面爬虫部分很有用)

查看你当前浏览器的ua:

image.png

实例:

import urllib.request
url = "http://www.baidu.com"
ua = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv2.0.1) Gecko/20100101 Firefox/4.0.1"
request = urllib.request.Request(url,headers={'User-Agent':ua})  # 实例化request对象
response = urllib.request.urlopen(request )
print(response.read().decode("utf-8"))

(4) 下载文件

request.urlretrieve(url, fileName)
参数:
url: 下载的url地址
fileName:保存到本地的文件名
实例:

from urllib import request
url = "http://www.sinaimg.cn/dy/slidenews/4_img/2009_44/163_13716_315914.jpg"
request.urlretrieve(url, "1.jpg")

上一篇下一篇

猜你喜欢

热点阅读