鱼C论坛

 找回密码
 立即注册

[技术交流] py3000愉快的开始

[复制链接]
 楼主| 发表于 2017-11-29 21:07:03 | 显示全部楼层

057论一只爬虫的自我修养5:正则表达式(中)

>>> import re
>>> re.search(r'FishC', 'I love FishC.com!')
!&*#@……*&@¥……*(
>>> re.search(r'\.', 'I love FishC.com!')
<_sre.SRE_Match object, span=(12, 13), match='.'>
在正则表达式中,反斜杠同样具有这剥夺元字符的特殊能力

元字符就是这个字符本身代表的其他含义,有特殊能力的字符,像这个点号,就是个元字符

>>> re.search(r'\d', 'I love 123 FishC.com!')
<_sre.SRE_Match object; span=(7, 8), match='1'>
>>> re.search(r'\d\d\d', 'I love 123 FishC.com!')
<_sre.SRE_Match object; span=(7, 10), match='123'>                #        然后就把123依次匹配下来了

结合以上两点知识就可以匹配一个IP地址
>>> re.search(r'\d\d\d.\d\d\d.\d\d\d.\d\d\d', '233.233.233.666')                #        反斜杠d表示匹配到数字是0~9,而IP地址的约定范围,每组数据是0~255,三个反斜杠d可以匹配到的最大数字是999,这里要求IP地址必须有三个数字,但是有的IP地址则是233,66,233之类的,有的只有两个数字
<_sre.SRE_Match object; span=(0, 15), match='233.233.233.666'>
>>>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-11-30 20:14:22 | 显示全部楼层

057论一只爬虫的自我修养5:正则表达式(中2)

>>> import re
>>> re.search(r'[aeiou]', 'I love FishC.com!')
<_sre.SRE_Match object; span=(3, 4), match='o'>                #        因为正则表达式自带大小写敏感模式,解决方案1、关闭大小写敏感模式  2、修改字符类,例如
>>> re.search(r'[aeiouAEIOU]', 'I love FishC.com!')
<_sre.SRE_Match object; span=(0, 1), match='I'>                #        字符类中的任何一个字符匹配成功,就算匹配成功,在中括号中,也可以使用一个小横杠-,来表示一个范围,例如
>>> re.search(r'[0-9]', 'I love 123 FishC.com!')
<_sre.SRE_Match object; span=(7, 8), match='1'>
>>> re.search(r'[2-9]', 'I love 123 FishC.com!')
<_sre.SRE_Match object; span=(8, 9), match='2'>
>>>
有关数字范围↑
——————————————————————————————
有关匹配个数↓
限定重复匹配的个数,可以使用大括号来解决,例如
>>> re.search(r'ab{3}c', 'abbbc')       
<_sre.SRE_Match object; span=(0, 5), match='abbbc'>                #        要重复多少次,大括号里就写上那个要重复次数的数字就行了       
>>> re.search(r'ab{3}c', 'abbbbbbbbc')                #        如果手滑多打了几个b,Ta就匹配不了了
>>> re.search(r'ab{3,10}c', 'abbbbbbbbc')        #        可以给Ta限制范围
<_sre.SRE_Match object; span=(0, 10), match='abbbbbbbbc'>                #        在3或10以内的b,Ta都会进行匹配
>>>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-11-30 21:27:15 | 显示全部楼层
摆渡终极鉴黄师 发表于 2017-7-7 00:00
>>> 3>2 and 1>> (3>2) and (1>> (3>2) and (1>2)
         False
         每次运行程序产生的 ...

这不是书上的内容吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-12-1 23:53:26 | 显示全部楼层

057论一只爬虫的自我修养5:正则表达式(下)

本帖最后由 摆渡终极鉴黄师 于 2017-12-2 01:34 编辑

>>> import re
>>> re.search(r'[0-255]', '188')
<_sre.SRE_Match object; span=(0, 1), match='1'>
>>> re.search(r'[0-2][0-5][0-5]', '188')
>>>
正则表达式匹配的是字符串,所以说,数字对于字符来说只有0到9这几个字符
>>> re.search(r'[01]\d\d|2[0-4]\d|25[0-5]', '188')                #        这跟逻辑或是一个道理,要么第一个成立,要么第二个成立,要么第三个成立,三个里面任何一个成立都是OK的
<_sre.SRE_Match object; span=(0, 3), match='188'>        #        现在来可以试试IP地址
>>> re.search(r'(([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])\.){3}([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5]', '233.233.6.6')                #        小括号起到的作用是分组,一个小组就是一个整体,后面{}里加上的就是重复的次数,一个小组的内容就要必须匹配,小组内容匹配完之后,再来匹配这个反斜杠点\.
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-12-1 23:53:57 | 显示全部楼层
moyuqqxing 发表于 2017-11-30 21:27
这不是书上的内容吗

是啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-12-2 10:58:49 | 显示全部楼层

058论一只爬虫的自我修养6:正则表达式2(上)

反斜杠与字符的combo                                                触发效果
\d                                                                匹配任何十进制数字;相当于类[0-9]
\D                                                                与\d相反,匹配任何非十进制数字的字符;相当于类[^0-9]
\s                                                                匹配任何空白字符(包含空格、换行符、制表符等);相当于类[\t\n\r\f\v]
\S                                                                与\s相反,匹配任何空白字符;相当于类[^ \t\n\r\f\v]
\w                                                                匹配任何单词字符,见上方解释
\W                                                                与\w相反
\b                                                                匹配单词的开始或结束
\B                                                                与\b相反

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-12-3 12:03:41 | 显示全部楼层

058论一只爬虫的自我修养6:正则表达式2(中)

|表示匹配正则表达式的A或者B,例如
>>> import re
>>> re.search(r"Fish(C|D)", "FishD")
<_sre.SRE_Match object; span=(0, 5), match='FishD'>
>>> re.search(r"Fish(C|D)", "FishC")
<_sre.SRE_Match object; span=(0, 5), match='FishC'>
>>> re.search(r"Fish(C|D)", "FishE")
>>>
^(脱字符)匹配输入字符串的开始位置,也就是确定一个位置,例如
>>> re.search(r"^FishC", "FishC")
<_sre.SRE_Match object; span=(0, 5), match='FishC'>
>>> re.search(r"^FishC", "f FishC")                #        必须是字符串的开始位置对应,所以这个不行
>>>
$(差不多就是和^反一反)匹配输入字符串的结束位置,例如
>>> re.search(r"FishC$", "loveFishC")
<_sre.SRE_Match object; span=(4, 9), match='FishC'>
>>> re.search(r"FishC$", "loveFiCh")        #        必须是字符串的结束位置对应,所以这个不行
>>>

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-12-4 20:10:22 | 显示全部楼层

058论一只爬虫的自我修养6:正则表达式2(中2)

本帖最后由 摆渡终极鉴黄师 于 2017-12-5 11:26 编辑

\将一个普通字符变为特殊字符,例如\d表示匹配所有十进制数字
结束元字符的特殊功能,例如\.表示点号本身
引用序号对应的子组匹配的字符串(反斜杠加上一个序号,后面的数字是1-99,Ta表示对应的组所匹配的字符串),例如
>>> import re
>>> re.search(r"(FishC)\1", "FishC.com")        #        子组就是括号括起来的
>>>
>>> re.search(r"(FishC)\1", "FishCFishC")
<_sre.SRE_Match object; span=(0, 10), match='FishCFishC'>                #        所以后面必须是FishC,Ta才可以匹配到
>>>

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-12-5 11:33:35 | 显示全部楼层

058论一只爬虫的自我修养6:正则表达式2(中3)

>>> import re
>>> re.search(r"(FishC)\060", "FishCFishC0")
>>> re.search(r"(FishC)\060", "FishCFishC0")                #        0的十六进制是三个0,转换成八进制就是60,这里是060,因为八进制的要求是三个数字来描述
<_sre.SRE_Match object; span=(5, 11), match='FishC0'>       
>>>
十进制的97对应的是小写字母a,八进制的话就是141
0开头的三位数或者直接一个三位数Ta都表示的是八进制
>>> re.search(r"(FishC)\141", "FishCFishCa")                #        十进制的97对应的是小写字母a,八进制的话就是141,0开头的三位数或者直接一个三位数Ta都表示的是八进制
<_sre.SRE_Match object; span=(5, 11), match='FishCa'>        #        匹配成功
>>>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-12-6 22:07:31 | 显示全部楼层

058论一只爬虫的自我修养6:正则表达式2)(中4)

本帖最后由 摆渡终极鉴黄师 于 2017-12-9 15:07 编辑

[...]字符类(就是字符集合的意思),匹配所包含的任意一个字符,被Ta包含在里面的字符都会失去特殊功能,就像反斜杠加上一个元字符,是一样的,例如
>>> import re
>>> re.search(r"[.]", "FishC.com")
<_sre.SRE_Match object; span=(5, 6), match='.'>
>>>
字符类的意思就是将Ta里边的内容当成普通的字符来看待,除了几个特殊的字符,例如小横杠-
findall方法是找到所有匹配的字符串,把Ta们打包成一个列表给返回,例如(当Ta遇到组或子组的时候也会有陷阱)
>>> re.findall(r"[a-z]", "FishC.com")
['i', 's', 'h', 'c', 'o', 'm']
>>>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-12-7 22:14:11 | 显示全部楼层

058论一只爬虫的自我修养6:正则表达式2(中5)

本帖最后由 摆渡终极鉴黄师 于 2017-12-9 15:08 编辑

反斜杠在字符类里边表示python的转义符,例如
>>> re.findall(r"[\n]", "FindC.com\n")
['\n']                #        直接就匹配回车这个符号
>>>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-12-9 15:17:37 | 显示全部楼层

058论一只爬虫的自我修养6:正则表达式2(中6)

>>> re.findall(r"[^a-z]", "FishC.com\n")                #        出了字符类里的内容其他的都匹配,就是取反的意思
['F', 'C', '.', '\n']
>>>
这个脱字符^只能放在最前面,如果放在后面的话就不是这样,就表示匹配脱字符本身,例如
>>> re.findall(r"[a-z^]", "FishC.com\n")
['i', 's', 'h', 'c', 'o', 'm']
>>>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-12-10 13:39:41 | 显示全部楼层

058论一只爬虫的自我修养6:正则表达式2(下)

* 匹配前面的字表达式零次或多次,等价于{0,}
+匹配前面的字表达式一次或多次,等价于{1,}
?匹配前面的字表达式零次或一次,等价于{0,1}

正则表达式默认是启用了贪婪的模式进行匹配的,贪婪就是贪心,也就是在符合的条件下,Ta会尽可能多的去匹配,例如
>>> import re
>>> s = "<html><title>I love FishC.com</title></html>"
>>> re.search(r"<.+>", s)        #        加号+表示重复前面任何内容,Ta遇到右尖括号>Ta会停下来,尽可能多找,找到最后,最后不匹配再倒着往回找到第一个匹配的时候Ta就停下来,所以Ta匹配了整个字符串
<_sre.SRE_Match object; span=(0, 44), match='<html><title>I love FishC.com</title></html>'>
>>>

在表示重复的元字符后面再加上一个问号,这时候问号?不代表0次或者1次,这时候问号代表非贪婪模式
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-12-11 21:01:11 | 显示全部楼层

059论一只爬虫的自我修养7:正则表达式3(上)

如果你需要重复地使用某个正则表达式,那么你可以先将该正则表达式编译成模式对象。需要使用re.compile()方法来编译
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-12-12 20:41:00 | 显示全部楼层

059论一只爬虫的自我修养7:正则表达式3(中)

VERBOSE使用这个标志后空格和#会被忽略(不包括反斜杠转义后的空格和#),例如
charref = re.compile(r"""
&[#]                #        开始引用
(
        0[0-7]+        #八进制
        |[0-9]+        #十进制
        |x[0-9a-fA-F]+                只留禁止
)
:        #结尾分号
""", re.VERBOSE)
————————
使用后代码看起来会舒服很多,要不然没空格会显得太复杂,例如
charref=re.compile("&#(0[0-7]+|[0-9]+|x[0-9a-fA-F]+);")
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-12-13 20:21:22 | 显示全部楼层

059论一只爬虫的自我修养7:正则表达式3(下)

本帖最后由 摆渡终极鉴黄师 于 2017-12-15 16:09 编辑

http://bbs.fishc.com/thread-57691-1-1.html
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-12-14 21:04:58 | 显示全部楼层

060论一只爬虫的自我修养8:正则表达式4(上)

本帖最后由 摆渡终极鉴黄师 于 2017-12-15 18:32 编辑

group方法,例如
>>> import re
>>> result = re.search(r" (\w+) (\w+)", "I love FishC.com!")
>>> result
<_sre.SRE_Match object; span=(1, 12), match=' love FishC'>
>>> result.group(1)
'love'
>>> result.group(2)
'FishC'
>>> result.group()
' love FishC'
>>>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-12-15 18:31:40 | 显示全部楼层

060论一只爬虫的自我修养8:正则表达式4(上2)

@&*……#*&!*(@
>>> result.start()        #        匹配的开始
1
>>> result.end()        #        匹配的结束
12
>>> result.span()        #匹配的范围
(1, 12)
>>>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-12-16 21:13:55 | 显示全部楼层

060论一只爬虫的自我修养8:正则表达式4(中)

import urllib.request
import re

def open_url(url):
    req = urllib.request.Request(url)
    req.add_header('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36')
    page = urllib.request.urlopen(req)
    html = page.read().decode('utf-8')

    return html

def get_img(html):
    p = r'<img class="BDE_Image" src="([^"]+\.jpg)"'        #        ^"表示除了这个双引号的之外的所有字符,可以用星号*重复0次或者用+加号重复一次或者多次一次或者多次,这个点.要加反斜杠\,要不然表示任何除了换行符之外其他的任何字符,加个小括号可以把地址提取出来
    imglist = re.findall(p, html)

    for each in imglist:
        filename = each.split("/")[-1]
        urllib.request.urlretrieve(each, filename, None)

   
if __name__ == '__main__':   
    url = "http://tieba.baidu.com/p/5481401082"
    get_img(open_url(url))
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-12-17 14:42:03 | 显示全部楼层

060论一只爬虫的自我修养8:正则表达式4(下)

(?:...)非捕获组,即该子组匹配的字符串无法从后边获取

小括号是元字符
import urllib.request
import re

def open_url(url):
    req = urllib.request.Request(url)
    req.add_header('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36')
    page = urllib.request.urlopen(req)
    html = page.read().decode('utf-8')

    return html

def get_img(html):
    p = r'(?:(?:[0,1]?\d?\d|2[0-4]\d|25[0-5])\.){3}(?:[0,1]?\d?\d|2[0-4]\d|25[0-5])'                #        也就是所有出现子组的位置问号冒号下去,这样就不会直接捕获了,也不会给变成子组显示出来
    iplist = re.findall(p, html)

    for each in iplist:
        print(each)

   
if __name__ == '__main__':   
    url = "!&*#……(*@&"
    get_img(open_url(url))
多练习就ok了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-19 07:57

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表