python爬虫(二)----正则表达式

正则表达式

本博客主要讲正则表达式在爬虫网页解析中的作用
需要的是python的re模块
python版本:3.x

(一) 正则表达式的基本知识

1 匹配字符
  • 常见匹配模式—匹配字符
模式描述
.匹配任意除\n(换行符)之外的字符
\转义字符
[…]用来表示一组字符,匹配[…]内的任意字符
^[…]匹配除了[…]内任意字符
  • 预定义字符
模式描述
\d匹配数字[0-9]
\D匹配非数字
\s匹配空白符
\S匹配非空白符
\w匹配26个字母 [a-z] [A-Z]
\W匹配非26字母
a | b匹配a或b
  • 数量词
模式描述
*匹配*号前的字符 [0–多次]
+匹配+号前的字符 [1–多次]
匹配?前的字符 [0-1次]
{m}匹配{}号前的字符m次
{m,n}匹配{}前的字符 [m-n次]
  • 边界匹配
模式描述
^匹配字符串开头:^abc匹配abc开头字符串
$匹配字符串结尾:xyz$匹配以xyz结尾的字符串
\A匹配字符串开始
\z匹配字符串结束
\Z匹配字符串结束,如果存在换行,只匹配到换行前的结束字符串
\G匹配最后匹配完成的位置
(…)表示一个表达式,也表示一个组,常见的是:(.*?)
  • 案例如下:
import re
content = 'Hello 123 4567 World_This is a Regex Demo'
# \s:匹配空白符
# \d:匹配数字
# \d{4}:匹配4个数字
# \w{10}:匹配10个单个字符
#.:匹配任意字符
#*:匹配0-多个表达式
result =re.match('^Hello\s\d\d\d\s\d{4}\s\w{10}.*',content)
# 改进 result =re.match('^He.*?(\d+)\s\d{4}\s\w{10}.*',content)
#因为没有组,所以为0
print(result.group(0))
#范围 输出结果是从0匹配到41
print(result.span())

'''
输出结果:
(0, 41)
Hello 123 4567 World_This is a Regex Demo
'''
2 匹配函数
  • 函数和描述
函数描述
re.match(pattern,content)从content字符串的起点开始匹配
re.search(pattern,content)对content做任意位置匹配
re.findall(pattern,content)从满足位置开始找出所有满足正则表达式的字符串,返回的是列表
re.finditer(pattern,content)从满足位置开始找出所有满足正则表达式的字符串,返回的是迭代器
  • 代码对比
import re
content = '''wo men Hello 1234567 World_This is
a Regex Demo
'''
result = re.match('He.*?(\d+).*?Demo',content,re.S)
result1 = re.search('He.*?(\d+).*?Demo',content,re.S)
print(result)
print(result1)

'''
输出:
None
<_sre.SRE_Match object; span=(7, 47), match='Hello 1234567 World_This is\na Regex Demo'>

'''

注意:当遇到有换行的时候要用 : re.S

3 贪婪和非贪婪匹配
  • 贪婪匹配:.*
#贪婪匹配
import re
content = 'Hello 1234567 World_This is a Regex Demo'
#.*:尽可能匹配多,而后面有个(\d+)中的+至少匹配一个,所以(\d+)匹配了7
result = re.match('^He.*(\d+).*Demo$',content)
#例如(\d*),由于*是匹配0-无限个,导致(\d*)没匹配到
result1 = re.match('^He.*(\d*).*Demo$',content)
print(result.group(1))
'''
输出:7
注意result1没有匹配到
'''
  • 非贪婪匹配:.*?
#非贪婪匹配: .*? : 匹配尽可能少的
import re 
content = 'Hello 1234567 World_This is a Regex Demo'
result = re.match('^He.*?(\d+).*Demo$',content) 
print(result.group(1))

'''
输出:1234567
'''

类似优先级:当时贪婪时优先级大于后面的匹配符
当时非贪婪时,优先级小于后面的匹配符

(二)豆瓣实战

  • 网页部分主要代码
    在这里插入图片描述

在这里插入图片描述
对HTML代码分析

<li class="">
            <div class="cover">
              <a href="https://book.douban.com/subject/30370935/?icn=index-editionrecommend" title="海胆">
                <img src="https://img3.doubanio.com/view/subject/m/public/s29918393.jpg" class="" width="115px" height="172px" alt="海胆">
              </a>
            </div>
                <div class="intervenor-info">
                    <img src="https://img3.doubanio.com/f/book/ef040178fab1770d60e3f2f12ba4c7aa70714396/pics/book/partner/jd_recommend.png" class="jd-icon" width="16" height="16"> 
                    <span>推荐</span>
                </div>
            <div class="info">
              <div class="title">
                <a class="" href="https://book.douban.com/subject/30370935/?icn=index-editionrecommend" title="海胆">海胆</a>
              </div>
              <div class="author">
                雷晓宇
              </div>
              <div class="more-meta">
                <h4 class="title">
                  海胆
                </h4>
                <p>
                  <span class="author">
                    雷晓宇
                  </span>
                  /
                  <span class="year">
                    2018-11
                  </span>
                  /
                  <span class="publisher">
                    浙江文艺出版社
                  </span>
                </p>
                <p class="abstract">
                  
                  《海胆》是一本人物特写集,收录了十篇文章,写出了十个人的秘密。
附赠朴树亲笔信。
之所以取名“海胆”,是因为这十个人都和海胆一样:有尖利的刺,也有柔软的心。
除了刷爆朋友圈的《和李安一起午餐》——对李安而言,电影的秘密可以讲,生活的秘密不可说。但他把生活秘密藏在电影里,看懂了,才是真正理解他了——还有:
《Hello,朴树先生》:用两万字告诉你,一个4...
                </p>
              </div>
            </div>
          </li>

在这里插入图片描述

写正则表达式:#从标签<li>开始,要注意标签闭合以防匹配失败
'<li.*?cover.*?href="(.*?)".?title="(.*?)".*?author">(.*?)</div>.*?year">(.*?)</span>'

  • 完整代码如下:
import requests
import re
content = requests.get('https://book.douban.com/').text
#print(content)
#别忘记标签闭合 不唯一
pattern = re.compile('<li.*?cover.*?href="(.*?)".*?title="(.*?)".*?more-meta.*?author">(.*?)</span>.*?year">(.*?)</span>.*?</li>',re.S)
result = re.findall(pattern,content)
#print(result)
for res in result:
    url,name,author,date = result
    author = re.sub('\s',''author)
    date = re.sub('\s',''date)
    print(url,name,author,date)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值