Python爬虫-正则表达式

本文详细介绍正则表达式的常用符号及方法,并通过实例演示如何使用findall、search和sub等函数进行文本匹配与替换。此外,还展示了如何利用正则表达式从网页中抓取特定信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

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

  1. 输出 ['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

 

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

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

 

完整代码

  1. import re
  2. a = 'xzx23'
  3.  
  4. # . :匹配任意字符,换行符\n除外
  5. # 点.是一个占位符,一个.代表一个符号
  6. b = re.findall('x.', a)
  7. print(". :匹配任意字符,换行符\\n除外:",b)
  8.  
  9. # * :匹配前一个字符0次或无限次
  10. # 依次匹配字符,有则显示,无则显示''(空)。
  11. c= re.findall('x*', a)
  12. print("* :匹配前一个字符0次或无限次:",c)
  13.  
  14. # 问号?
  15. # ? :匹配前一个字符0次或1次
  16. # 单独与*一样,前面附加其他的符号将做非贪心限制
  17. d= re.findall('x?', a)
  18. print("? :匹配前一个字符0次或1次:",d)
  19.  
  20. # 贪心.*
  21. # 只要满足条件全部显示,贪心算法
  22. secret_code = 'ghkj08hs68xxIxxa14kgj4w314exxlovexxbvk14rgjhxxyouxxfj4286ykjhag2'
  23. e = re.findall('xx.*xx', secret_code)
  24. print ("贪心.*:",e)
  25.  
  26. # 非贪心.*?
  27. secret_code = 'ghkj08hs68xxIxxa14kgj4w314exxlovexxbvk14rgjhxxyouxxfj4286ykjhag2'
  28. f = re.findall('xx.*?xx', secret_code)
  29. print ("非贪心.*?:",f)
  30.  
  31. # () :括号内的数据作为结果返回
  32. # ()包围所需要的内容,括号内的内容作为结果返回,不需要的内容放在括号外面
  33. secret_code = 'ghkj08hs68xxIxxa14kgj4w314exxlovexxbvk14rgjhxxyouxxfj4286ykjhag2'
  34. g = re.findall('xx(.*?)xx', secret_code)
  35. print ("非贪心.*?:",g)
  36.  
  37.  
  38.  
  39. # sub将符合条件的()内内容提换
  40. # sub:替换符合规律的内容,返回替换后的值
  41. s = '123abcssfasdfas123'
  42. output = re.sub('123(.*?)123', '123789123', s)
  43. print ('sub将符合条件的()内内容提换:',output)
  44.  
  45.  
  46.  
  47. # re.S让.匹配所有行,包括了换行符(以\n的形式出现)
  48.  
  49. # search 找到一个后返回,不继续,大大提高效率
  50. # findall遍历全部,找到尽可能多的项
  51. s2 = '''ghkj08hs68xxIxx123xxlove
  52. xxbvk14rgjhxxfj4286ykjhag2'''
  53. b = re.search('xx(.*?)xx(.*?)xx', s2, re.S)
  54. print ('search 找到一个后返回,不继续,大大提高效率:',b)
  55. # 输出
  56. # < _sre.SRE_Match
  57. # object;
  58. # span = (10, 20), match = 'xxIxx123xx' >
  59.  
  60. # group是按括号顺序匹配
  61. b = re.search('xx(.*?)xx(.*?)xx', s2, re.S).group(1)
  62. print ('search 找到一个后返回,不继续,大大提高效率:',b)
  63. # .group(3)报错
  64. # Traceback (most recent call last):
  65. # File "D:/WorkSpace/python/PycharmProjects/爬虫/代码/Python-master/ReDemo.py", line 61, in <module>
  66. # b = re.search('xx(.*?)xx(.*?)xx', s2, re.S).group(3)
  67. # IndexError: no such group
  68.  
  69. # 每一个匹配项为第一级列表,括号为二级列表
  70. s2 = '''ghkj08hs68xxIxx123xxlovexxbvk14rgjhxxfj4286ykjhag2'''
  71. f2 = re.findall('xx(.*?)xx123xx(.*?)xx', s2, re.S)
  72. 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.youkuaiyun.com/SkyeyesXY/article/details/50837984

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值