4.3.1 re模块(正则表达式)

正则表达式的元字符有. ^ $ * ? { [ ] | ( )
.表示任意字符
[]用来匹配一个指定的字符类别,所谓的字符类别就是你想匹配的一个字符集,对于字符集中的字符可以理解成或的关系。
^ 如果放在字符串的开头,则表示取非的意思。[^5]表示除了5之外的其他字符。而如果^不在字符串的开头,则表示它本身。

具有重复功能的元字符:
* 对于前一个字符重复0到无穷次
+对于前一个字符重复1到无穷次
?对于前一个字符重复0到1次
{m,n} 对于前一个字符重复次数在为m到n次,其中,{0,} = *,{1,} = , {0,1} = ?
{m} 对于前一个字符重复m次

\d 匹配任何十进制数;它相当于类 [0-9]。
\D 匹配任何非数字字符;它相当于类 [^0-9]。
\s 匹配任何空白字符;它相当于类 [ fv]。
\S 匹配任何非空白字符;它相当于类 [^ fv]。
\w 匹配任何字母数字字符;它相当于类 [a-zA-Z0-9_]。
\W 匹配任何非字母数字字符;它相当于类 [^a-zA-Z0-9_]。

1.元字符([ ]),它用来指定一个character class。所谓character classes就是你想要匹配的字符(character)的集合.字符(character)可以单个的列出,也可以通过”-“来分隔两个字符来表示一 个范围。例如,[abc]匹配a,b或者c当中任意一个字符,[abc]也可以用字符区间来表示—[a-c].如果想要匹配单个大写字母,你可以用 [A-Z]。
2.元字符[^]. 你可以用补集来匹配不在区间范围内的字符。其做法是把”^”作为类别的首个字符;其它地方的”^”只会简单匹配 “^”字符本身。例如,[^5] 将匹配除 “5” 之外的任意字符。同时,在[ ]外,元字符^表示匹配字符串的开始,如”^ab+”表示以ab开头的字符串。

>>> m=re.search("ab+","asdfabbbbcd")
>>> print m.group()
abbbb

这里的+代表字符串ab后面有多少b都可以被打印出来。

>>> m=re.search("ab","asdfabbbbcd"
>>> print m.group()
ab

如果没有+,ab只打印一次。search一般从字符的任意位置开始匹配。

3.”^”在不同位置所代表的意义。

  >>> re.search("[^abc]","abcd")  #"^"在首字符表示取反,即abc之 外的任意字符。
 <_sre.SRE_Match object at 0x011B19F8>
 >>> m=re.search("[^abc]","abcd")
 >>> m.group()
 'd'
 >>> m=re.search("[abc^]","^")  #如果"^"在[ ]中不是首字符,那么那就是一个普通字符
 >>> m.group()
 '^'

4.元字符($)匹配字符串的结尾或者字符串结尾的换行之前。

>>> re.findall("foo.$","foo1\nfoo2\n")
['foo2']
>>> re.findall("foo$","foo1\nfoo2\n")
[]
>>> re.findall("foo$","foo1\nfoo\n")
['foo']
>>> re.findall("foo.$","foo1\nfoo23\n")
[]

“.” 表示可以匹配任意一个字符,且只能匹配一个字符,$从字符串后面开始匹配,所以得到上述结果。

search和findall的区别:
search找到就返回,不会找到所有的,找不到就返回none;
findall会找到所有的。

>>> m=re.search("abcd", '1abcd2abcd')
>>> m.group()  #找到即返回一个match object,然后根据该对象的方法,查找匹配到的结果。
 'abcd'
>>> re.findall("abcd","1abcd2abcd")
 ['abcd', 'abcd']

爬取猫眼电影网站的电影信息:

#!/usr/bin/env python
#-*- coding: GBK -*-
__author__ = 'Diao'

import re
import urllib2

class TodayMovie(object):
    '''获取影院当日影视'''
    def __init__(self):
        self.url ='http://maoyan.com/'
        self.timeout = 5
        self.fileName = './todayMovie.txt'
        '''定义内部变量'''
        self.getMovieInfo()

    def getMovieInfo(self):

        response = urllib2.urlopen(self.url,timeout=self.timeout)

        movieList1 = re.findall('title=.*',response.read())
        movieList2 = re.findall('ranking-movie-name">.*', response.read())

        with open(self.fileName,'a') as fp:
            for movie in movieList1:
                movie = self.subStr1(movie)
                print(movie.decode('utf8'))
                fp.write(movie + '\n')


        with open(self.fileName,'a') as fp:
            for movie in movieList2:
                movie = self.subStr2(movie)
                print(movie.decode('utf8'))
                fp.write(movie + '\n')

    def subStr1(self, st):
        st = st.replace('title=','')
        st = st.replace('</div>', '')
        st = st.replace('>', '')

        return st

    def subStr2(self, st):
        st = st.replace('</span>', '')
        st = st.replace('ranking-movie-name">', '')
        st = st.replace('</div>', '')
        return st



if __name__ == '__main__':
    tm = TodayMovie()

这里写图片描述

第一次写 ,质量不好,这里的抓取电影,有两种格式,所以抓的时候分两次抓的,我本来想能不能利用循环可以执行一次程序就把所有都抓出来,但是水平有限,不会用循环,所以就将程序执行两次,写入文件时,将文件写入方式改为‘a’,python程序顺序执行,我把movieList1 = re.findall(‘title=.*’,response.read())
放前面,就执行这个,另一个就不执行了。还有就是后面抓的电影名称重复两次,我不知道怎么去除一次。第一次写,总算爬出来了,后面再。继续学习

猜你喜欢

转载自blog.csdn.net/qq_30614451/article/details/82051909