您的位置:首页 > 编程语言 > Python开发

Python分布式爬虫前菜(2):关于提取网页源码中特定信息的技巧

2017-03-06 16:07 519 查看
前面介绍了不同方法来获取静态和动态各类网页源码,可是我们知道网页源码是夹杂着各种文字和代码的让人非常眼花缭乱的信息。如何从中提取出有用的信息是一次有意义的爬虫过程中不可避免的问题。这里我们需要快速简洁的工具帮我们完成,其中就有re,BeautifulSoup和XPath等优秀代表。闲话不说,直接进入主题:

(一)re(regular expression operations),即我们常说的正则表达式。它是针对字符数操作的逻辑公式,根据建立的一组规则字符串对需操作的字符进行逻辑过滤。例如:

#建立逻辑规则,使用re.compile
pattern = re.compile('http://[a-z]{2}.xxx.com/[a-z]+/g[0-9]+[/]*$')
#测试是否匹配,若不匹配则不返回任何东西,以下是匹配模式
re.match(pattern,'http://gd.xxx.com/wcubuw/g36232/')
以上方法可以挑出我们所需的链接类型,那么'http://[a-z]{2}.xxx.com/[a-z]+/g[0-9]+[/]*$'具体都代表什么意思呢?

1. [a-z]代表全部的小写字母,同样[0-9]代表数字,而[B-E]则是代表B到E之间的几个大写字母,即可以把我们需要匹配的字符放在[]括号中。

2. {2}代表前面的字符的个数为2,即指定了数量。而如果在字符后面使用?代表这个字符重复0或1次,*代表这个字符重复0或不限数,+则代表这个字符重复1或大于1次。

3. 点 . 匹配除换行符'\n'外的任意字符,若是在DOTALL模式下,即使用re.S则连换行符也可匹配。

4. 所以g[0-9]+的意思便是字符g后边连接大于等于1个的数字符号便可匹配。

5. [/]*$是什么意思呢?我们知道[/]即是符号'/',[/]*就是有一个或零个'/'字符,而$则代表是结尾。

除了上述书写规则外,还有一些其它的形式。通过这些规则写好的规则字符串使用re.compile('规则字符串'),便可以生成我们需要的匹配模式pattern对象咯。

在Python 自带的re中,有了pattern对象便可以使用如下方法:

re.match(pattern, string, flags=0)
re.search(pattern, string, flags=0)
re.split(pattern, string, maxsplit=0,flags=0)
re.findall(pattern, string, flags=0)
re.finditer(pattern, string, flags)
re.sub(pattern, repl, string, count)
re.subn(pattern, repl, string, count)

re.
search
()和
re.
match
()都是寻找字符串中是否匹配,不同的是前者检测字符串的每个位置,而后者检测位于首位置的匹配。

>>> re.match("c", "abcdef") # No match
>>> re.search("c", "abcdef") # Match
<_sre.SRE_Match object at ...>
#使用'^'时,则会限制只匹配从首位开始的
>>> re.match("c", "abcdef") # No match
>>> re.search("^c", "abcdef") # No match
>>> re.search("^a", "abcdef") # Match
<_sre.SRE_Match object at ...>
#但在MUTILINE模式中,match()只匹配首行,search()会检测各行,如:
>>> re.match('X', 'A\nB\nX', re.MULTILINE) # No match
>>> re.search('^X', 'A\nB\nX', re.MULTILINE) # Match
<_sre.SRE_Match object at ...>
re.
split
(pattern, string, maxsplit=0, flags=0)是按模式切割字符串的。maxsplit为零时是全部切割,若为正整数则指明切割的切口数量。如:
#re.IGNORECASE模式表明大小写不敏感
>>> re.split('[a-f]+', '0a3B9yy213b1ff2', maxsplit=3,flags=re.IGNORECASE)
['0', '3', '9yy213', '1ff2']
re.
findall
(pattern, string, flags=0)返回匹配的字段列表,例子:
#'\d+'转义字符\和d组合的'\d'等同于[0-9]
>>> re.findall('\d+','dwh8281wgb122ge219ye1')
['8281', '122', '219', '1']
re.
sub
(pattern, repl, string, count=0, flags=0)根据pattern匹配字符段,使用repl的要求替换string中对应的字符段。repl可以是方法和字符串:
#将'AND'替换为'&'
>>> re.sub(r'\sAND\s', ' & ', 'Baked Beans And Spam', flags=re.IGNORECASE)
'Baked Beans & Spam'
#也可以创建个函数
>>> def func(matchobj):
... return matchobj.group(2).title()+'|||'+matchobj.group(1).upper()
>>> re.sub('(\w+) (\w+)',func,'hello world,love husky!!')
'World|||HELLO,Husky|||LOVE!!'更多内容可以参考re
未完待续。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息