Python网络爬虫学习日志02

正则表达式

正则表达式常用符号

  • 一般字符

正则表达式的一般字符有三个

字符

含义

.

匹配任意单个字符(不包括换行符\n)

\

转义字符(把有特殊意义的字符转换成字面意思)

[…]

字符集。对应字符集中的任意字符

说明:

  1. “ . ”字符为匹配任意单个字符,例如,a.c可以匹配结果为abc、aic、a&c等,但不包括换行符。
  2. “ \ “字符为转义字符,可以把字符改变为原来的意思。听上去不是很好理解,例如“ . ”字符是匹配任意单个字符,但有时不需要这个功能,只想让它表示一个点,这时就可以使用“\.”,就能匹配为“.”了。
  3. […]为字符集,相当于在中括号中任选一个。例如a[bcd],匹配的结果为ab、ac、ad。
  • 预定义字符集

正则表达式预定义字符集有6个

预定义字符集

含义

\d

匹配一个数字字符。等价于[0-9]

\D

匹配一个非数字字符。等价于[^0-9]

\s

匹配任何空白字符,包括空格、制表符、换页符等。等价于[\f\n\r\t\v]

\S

匹配任何空白字符,等价于[^\f\n\r\t\v]

\w

匹配包括下划线的任何单词字符,等价于’[A-Za-z0-9]’

\W

匹配任何非单词字符。等价于’[^A-Za-z0-9]’

正则表达式的预定义字符集易于理解,在爬虫实战中,常常会匹配数字而过滤掉文字部分信息。例如“字数3450”,只需要数字信息,可以通过“\d+”来匹配数据,“+”为数量词,这样便可以匹配到所以的数字

  • 数量词

正则表达式中的数量词列表如下

数量词

含义

*

匹配前一个字符0或无限次。例如:ab*c匹配ac、abc、abbc和abbbc等

+

匹配前一个字符1或无限次。例如:ab+c匹配abc、abbc和abbbc等

?

匹配前一个字符0或1次。例如:ab?c匹配ac和abc

{m}

匹配前一个字符m次。例如:ab{3}c匹配abbbc。

{m,n}

匹配前一个字符m至n次。例如:ab{1,3}c匹配abc、abbc和abbbc、

  • 边界匹配

边界匹配的关键字符:

边界匹配

含义

^

匹配字符串开头,例如,^abc匹配abc开头的字符串

$

匹配字符串结尾。例如:abc$匹配abc结尾的字符串

\A

仅匹配字符串开头。例如:\Aabc

\Z

仅匹配字符串结尾。例如:abc\Z

边界匹配在爬虫实战中使用较少,因为爬虫提取的数据大部分为标签中的数据,例如:<span class=”stats-vote”><I class=”number”>186</i> 好笑</span>中提取数字信息,边界匹配在这里没有任何作用。

爬虫实战中常用的(.*?),”()”表示括号的内容作为返回结果,”.*?”是非贪心算法,匹配任意的字符。例如,字符串'xxIxxjshdxxlovexxsffaxxpythonxx',可以通过’xx(.*?)xx’匹配符合这种规则的字符串,代码如下:

import re
a = 'xxIxxjshdxxlovexxsffaxxpythonxx'
infos = re.findall('xx(.*?)xx',a)
print(infos)

运行结果如下

re模块及方法

re模块使python语言拥有全部的正则表达式功能,这里主要是常用的三种函数使用方法

  • search()函数

re模块的search()函数匹配并提取第一个符合规律的内容,返回一个正则表达式对象。

search()函数语法如下:

re.match(pattern,string,flags=0)

其中:

  1. pattern为匹配的正则表达式。
  2. string为要匹配的字符串。
  3. flags为标志位,用于控制正则表达式的匹配方式,如是否区分大小写,多行匹配等

例如:

import re
a = 'one1two2three3'
infos = re.search('\d+',a)
print(infos)                #search方法返回的是正则表达式对象

可以看出,search()函数返回的是正则表达式对象,通过正则表达式匹配到了“1”这个字符串,可以通过下面的代码返回匹配到的字符串:

import re
a = 'one1two2three3'
infos = re.search('\d+',a)
print(infos.group())

  • sub()函数

re模块提供了sub()函数用于替换字符串中的匹配项,sub()函数的语法如下:

re.sub(pattern,repl,string,  count=0, flags=0)

其中:

  1. pattern为匹配的正则表达式。
  2. repl为替换的字符串。
  3. string为要被查找替换的原始字符串。
  4. counts为模式匹配后替换的虽大次数,默认0表示替换所有的匹配。
  5. flags为标志位,用于控制正则表达式的匹配方式,如是否区分大小写,多行匹配等。

例如,一个电话号码123-4567-1234,通过sub()函数把中间的“-”去除掉,可以通过如下代码实现:

import re
phone = '123-4567-1234'
new_phone = re.sub('\D','',phone)
print(new_phone)

sub()函数的用途类似于字符串中的replace()函数,但sub()函数更加灵活,可以通过正则表达式来匹配需要替换的字符串,而replace()函数却做不到的。在爬虫实战中sub()函数的使用也是极少的,因为爬虫所需的是爬取数据,而不是替换数据。

  • findall()函数

findall()函数匹配所有符合规律的内容,并以列表的形式返回结果。例如,前面的’one1two2three3’,通过search()函数只能匹配到第一个符合规律的结果,而通过findall()函数可以返回所有数字。

import re
a = 'one1two2three3'
infos = re.findall('\d+',a)
print(infos)

在爬虫实战中,findall()的使用频率最多,下面以前面爬取动漫花园的数据为例,看一下通过正则表达式如何提取所需的信息,通过观察网页源代码可以看出,动漫资源的存储大小都是在<td class="size">(数据量)</td>这个标签中

这时就可以通过构建正则表达式和findall()函数来获取视频资源的存储大小:

import re
import requests

res = requests.get('https://acg.rip/')
prices = re.findall('<td class="size">(.*?)</td>', res.text)
for price in prices:
    print(price)

结果如图

不难看出,通过正则表达式的方法爬取数据,比之前的方法代码更少也更简单,那是因为少了解析数据这一步,通过Requests库请求返回的Html文件就是字符串的类型,代码可以直接通过正则表达式来获取数据。

  • re模块修饰符

re模块中包含一些可选标志修饰符来控制匹配的模式

修饰符

描述

re.l

使匹配对大小写不敏感

re.L

做本地化识别(locale-aware)匹配

re.M

多行匹配,影响^和$

re.S

使匹配包括换行在内的所有字符

re.U

根据Unicode字符集解析字符,这个影响\w,\W,\b,\B

re.X

该标志通过给予更灵活的格式,以便将正则表达式写的更易理解

在爬虫中re.S是最常用的修饰符,它能够换行匹配。在这里举个简单的例子,例如提取<div>指数</div>中的文字,可以通过以下代码实现

import re
a = '<div>指数</div>'
word = re.findall('<div>(.*?)</div>',a)
print(word)

但如果字符串是下面这样的就匹配不到div标签中的文字信息

这是因为findall()函数是逐行匹配的,当第一行没有匹配到数据时,就会从第二行重新匹配,这样就没办法匹配到div标签中的文字信息,这时就可通过re.S来进行跨行匹配。

import re
a = '''<div>指数
</div>'''
word = re.findall('<div>(.*?)</div>',a,re.S)
print(word)

从结果中可以看出,跨行匹配的结果会有一个换行符,这种数据需要清洗才能存入数据库,可以通过strip()方法去除换行符

综合案例———爬取网络小说

利用Requests库和正则表达式方法,爬取飞卢小说网(https://b.faloo.com/1142238_1.html)中该小说的全文信息,并把爬取的数据存储到本地文件

思路:

手动浏览前5章的网址

https://b.faloo.com/1142238_1.html

https://b.faloo.com/1142238_2.html

https://b.faloo.com/1142238_3.html

https://b.faloo.com/1142238_4.html

https://b.faloo.com/1142238_5.html

可以看到有明显的规律,通过数字递加来分页。为避免因为404错误而停止爬取,从第一章开始构造URL,中间有404错误就跳过不怕去。

运用python对文件的操作,把爬取的信息存储在本地txt文本中。

爬虫代码如下:

import requests
import re
import time
headers = {'User-Agent':"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36"}


f = open('E:/python/GUIMI/test.txt','a+')

def get_info(url):
   res =requests.get(url,headers=headers)
   if res.status_code == 200:
       contents = re.findall('<p>(.*?)</p>',res.content.decode('gbk'),re.S)
       for content in contents:
           f.write(content+'\n')
   else:
       pass

if __name__ == '__main__':
    urls = ['https://b.faloo.com/1142238_{}.html'.format(str(i)) for i in range(1,44)]
    for url in urls:
        get_info(url)
        time.sleep(1)

f.close()

运行结果:

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值