Python爬虫-正则表达式

xiaoxiao2021-02-28  75

 

1.正则表达式的符号与方法

常用符号:点号,星号,问号与括号(小括号)

. :匹配任意字符,换行符\n除外* :匹配前一个字符0次或无限次? :匹配前一个字符0次或1次.* :贪心算法.*? :非贪心算法() :括号内的数据作为结果返回

常用方法:findall, search, sub

findall:匹配所有符合规律的内容,返回包含结果的列表search:匹配并提取第一个规律的内容,返回一个正则表达式对象(object)sub:替换符合规律的内容,返回替换后的值

1)findall

a.点号.

import re

a = 'xzx23'

b = re.findall('x.', a)

print b

输出 ['xz', 'x2']

 

点.是一个占位符,一个.代表一个符号

b.星号*

import re a = 'xyxy123' b = re.findall('x*', a) print b

 

输出['x', '', 'x', '', '', '', '', '']

依次匹配字符,有则显示,无则显示''(空)。

c.问号?

import re a = 'xy123' b = re.findall('x?', a) print b

 

单独与*一样,前面附加其他的符号将做非贪心限制

d.贪心.*

import re secret_code = 'ghkj08hs68xxIxxa14kgj4w314exxlovexxbvk14rgjhxxyouxxfj4286ykjhag2' b = re.findall('xx.*xx', secret_code) print b

 

输出['xxIxxa14kgj4w314exxlovexxbvk14rgjhxxyouxx']

只要满足条件全部显示,贪心算法

e.非贪心.*?

b = re.findall('xx.*?xx', secret_code)

 

输出['xxIxx', 'xxlovexx', 'xxyouxx']

以上只做了解,一般只用(.*?)

f.经典用法(.*?)

b = re.findall('xx(.*?)xx', secret_code)

 

输出['I', 'love', 'you']

()包围所需要的内容,括号内的内容作为结果返回,不需要的内容放在括号外面

2)re.S

import re secret_code = '''ghkj08hs68xxIxxa14kgj4w314exxlove xxbvk14rgjhxxyouxxfj4286ykjhag2''' #love后有换行符 b = re.findall('xx(.*?)xx', secret_code) print b

 

输出['I', 'bvk14rgjh'],因为.不能匹配换行符。所以会一行为一个搜索项去找。匹配任何字符除了新的一行 import re secret_code = '''ghkj08hs68xxIxxa14kgj4w314exxlove xxbvk14rgjhxxyouxxfj4286ykjhag2''' #love后有换行符 b = re.findall('xx(.*?)xx', secret_code, re.S) print b 输出['I', 'love\n', 'you'],re.S让.匹配所有行,包括了换行符(以\n的形式出现)

3)search

对比search和findall的区别

search 找到一个后返回,不继续,大大提高效率findall遍历全部,找到尽可能多的项 import re s2 = '''ghkj08hs68xxIxx123xxlove xxbvk14rgjhxxfj4286ykjhag2''' b = re.search('xx(.*?)xx(.*?)xx', s2, re.S).group(1) print b

 

输出I.group(2)输出love.group(3)报错

group是按括号顺序匹配

import re s2 = '''ghkj08hs68xxIxx123xxlovexxbvk14rgjhxxfj4286ykjhag2''' f2 = re.findall('xx(.*?)xx123xx(.*?)xx', s2, re.S) print f2[0][1]

 

输出love

每一个匹配项为第一级列表,括号为二级列表

4)sub

import re s = '123abcssfasdfas123' output = re.sub('123(.*?)123', '123789123', s) print output

 

输出123789123sub将符合条件的()内内容提换

5)注意:

from re import findall, search, S  最好不要引入,因为S等容易和变量等混淆,引起歧义

6)compile用法

import re secret_code = '''ghkj08hs68xxIxxa14kgj4w314exxlove xxbvk14rgjhxxyouxxfj4286ykjhag2''' pattern = 'xx(.*?)xx' new_pattern = re.compile(pattern, re.S) b = re.findall(new_pattern, secret_code) print b

 

因为findall自动调用compile方法,所以不先编译规律compile再匹配

7)匹配纯数字(\d+)

import re a = 'dfhkgh43gfhja873y5t2167715' b = re.findall('(\d+)', a) print b

 

输出['43', '873', '5', '2167715']

2.应用举例

1)用findall和search从大量文本中匹配内容

a.提取标题

import re old_url = 'http://www.jikexueyuan.com/course/android/?pageNum=2' total_page = 20 f = open('text.txt', 'r') html = f.read() f.close() title = re.search('<title>(.*?)</title>', html, re.S).group(1) print title

 

text.txt

<html> <head> <title>极客学院爬虫测试</title> </head> <body> <div class="topic"><a href="http://jikexueyuan.com/welcome.html">欢迎参加《Python定向爬虫入门》</a> <div class="list"> <ul> <li><a href="http://jikexueyuan.com/1.html">这是第一条</a></li> <li><a href="http://jikexueyuan.com/2.html">这是第二条</a></li> <li><a href="http://jikexueyuan.com/3.html">这是第三条</a></li> </ul> </div> </div> </body> </html>

 

输出极客学院爬虫测试

b.提取网址

link = re.findall('href="(.*?)"', html, re.S) for each in link: print each

 

输出

http://jikexueyuan.com/welcome.html http://jikexueyuan.com/1.html http://jikexueyuan.com/2.html http://jikexueyuan.com/3.html

c.提取文字信息

先爬大再爬小

text_fied = re.findall('<ul>(.*?)</ul>', html, re.S)[0] the_text = re.findall('">(.*?)</a>', text_fied, re.S) for every_text in the_text: print every_text

 

2)用sub实现翻页功能

for i in range(2, total_page+1): new_link = re.sub('pageNum=\d+', 'pageNum=%d'%i, old_url, re.S) print new_link

 

完整代码

import rea = 'xzx23' # . :匹配任意字符,换行符\n除外# 点.是一个占位符,一个.代表一个符号b = re.findall('x.', a)print(". :匹配任意字符,换行符\\n除外:",b) # * :匹配前一个字符0次或无限次# 依次匹配字符,有则显示,无则显示''(空)。c= re.findall('x*', a)print("* :匹配前一个字符0次或无限次:",c) # 问号?# ? :匹配前一个字符0次或1次# 单独与*一样,前面附加其他的符号将做非贪心限制d= re.findall('x?', a)print("? :匹配前一个字符0次或1次:",d) # 贪心.*# 只要满足条件全部显示,贪心算法secret_code = 'ghkj08hs68xxIxxa14kgj4w314exxlovexxbvk14rgjhxxyouxxfj4286ykjhag2'e = re.findall('xx.*xx', secret_code)print ("贪心.*:",e) # 非贪心.*?secret_code = 'ghkj08hs68xxIxxa14kgj4w314exxlovexxbvk14rgjhxxyouxxfj4286ykjhag2'f = re.findall('xx.*?xx', secret_code)print ("非贪心.*?:",f) # () :括号内的数据作为结果返回# ()包围所需要的内容,括号内的内容作为结果返回,不需要的内容放在括号外面secret_code = 'ghkj08hs68xxIxxa14kgj4w314exxlovexxbvk14rgjhxxyouxxfj4286ykjhag2'g = re.findall('xx(.*?)xx', secret_code)print ("非贪心.*?:",g)   # sub将符合条件的()内内容提换# sub:替换符合规律的内容,返回替换后的值s = '123abcssfasdfas123'output = re.sub('123(.*?)123', '123789123', s)print ('sub将符合条件的()内内容提换:',output)   # re.S让.匹配所有行,包括了换行符(以\n的形式出现) # search 找到一个后返回,不继续,大大提高效率# findall遍历全部,找到尽可能多的项s2 = '''ghkj08hs68xxIxx123xxlovexxbvk14rgjhxxfj4286ykjhag2'''b = re.search('xx(.*?)xx(.*?)xx', s2, re.S)print ('search 找到一个后返回,不继续,大大提高效率:',b)# 输出# < _sre.SRE_Match# object;# span = (10, 20), match = 'xxIxx123xx' > # group是按括号顺序匹配b = re.search('xx(.*?)xx(.*?)xx', s2, re.S).group(1)print ('search 找到一个后返回,不继续,大大提高效率:',b)# .group(3)报错# Traceback (most recent call last):# File "D:/WorkSpace/python/PycharmProjects/爬虫/代码/Python-master/ReDemo.py", line 61, in <module># b = re.search('xx(.*?)xx(.*?)xx', s2, re.S).group(3)# IndexError: no such group # 每一个匹配项为第一级列表,括号为二级列表s2 = '''ghkj08hs68xxIxx123xxlovexxbvk14rgjhxxfj4286ykjhag2'''f2 = re.findall('xx(.*?)xx123xx(.*?)xx', s2, re.S)print ('每一个匹配项为第一级列表,括号为二级列表:',f2[0][1])

 

3.实战

目标网站:http://www.jikexueyuan.com/  目标内容:课程图片  实现原理:

1.保存网页的源代码2.Python读文件加载源代码3.正则表达式提取图片网址4.下载图片

文本爬虫,半自动爬虫,人工爬虫

import re import requests f = open('sourse.txt', 'r') html = f.read() f.close() pic_url = re.findall('img src="(.*?)" class="lessonimg"', html, re.S) i = 0 for each in pic_url: print 'now downloading:' + each pic = requests.get(each) fp = open('pic\\' + str(i) + '.jpg', 'wb') fp.write(pic.content) fp.close() i += 1

 

import requests实现保存图片的功能

 

 来源: http://blog.csdn.net/SkyeyesXY/article/details/50837984

转载请注明原文地址: https://www.6miu.com/read-38681.html

最新回复(0)