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

python爬虫学习之路(二)

2020-01-14 08:49 99 查看

python基础爬虫学习之路(二)

在上一篇文章中,我们已经学习了有关爬虫对URL的访问以及利用xpath表达式对网页中的信息进行提取,这一篇文章我们将从信息提取的角度来进一步学习爬虫。

正则表达式提取信息

在学习正则表达式之前我们简单地说说什么是正则表达式。正则表达式通俗来说就是一种用来寻找规定模式字符串的逻辑表达式,再python中就是一个字符串,很多人觉得正则表达式在提取网页信息的时候并不是特别方便,但其实正则表达式有时候会比较灵活,对于特殊的需求它也能够满足。

我们先来了解一下python中正则表达式中的第三方库re

re这个库中比较常用的函数有下面这些,大家不用着急知道怎么用先随便看看就好,不会也不影响后面的阅读。

re.compile(string[,flag]):
将字符串编译成pattern
re.match(pattern,string[,flags]):
匹配字符串string中满足该模式的字符(从字符串头部开始匹配,如果开头不满足,哪怕中间有满足的也没用)返回Match对象
re.search(pattern,string[,flags]):
和match方法相类似,也是匹配字符串string中满足该模式的字符,区别在于它是全字符串扫描的,中间有满足条件的它也能找到并返回Match对象
re.split(pattern,string[,maxsplit])
按照能够匹配的子串将string分割后返回列表,maxsplit表示指定的最大分割次数。说白了就是你匹配出来的子字符串变成了原来字符串的分割点,然后将被分割后的字符串输出出来
re.findall(pattern,string[,flags])
这个方法是用来搜索整个string,以列表形式返回能匹配到的全部子串
re.finditer(pattern,string[,flags])
搜索整个string,以迭代器的形式返回能匹配到的全部Match对象
re.sub(pattern,repl,string[,count])
使用repl替换string中每一个匹配到的子串后返回替换后的字符串,count用来指定最多替换次数,省略时全部替换。除此之外,里面的pattern还可以时一个方法,这里就先不展开了。
re.subn(pattern,repl,string[,count])
返回上面sub的方法的替换次数

是不是感觉不能呼吸了,这也太多了吧,不过没关系,我们只要先学习几个比较简单的,剩下的高级功能也就自然能够理解了。

我们先看一下第一个compile函数,这个函数将一个正则表达式的字符串转化为pattern匹配对象,什么意思呢,就是它把它的那个字符串参数变成了一个新的对象,这个对象叫做pattern匹配对象,这个对象的作用就是用来给匹配函数作为参数的,别的匹配函数看不懂字符串,但是你用compile函数给这个字符串编译一下再传给它们,它们就能理解了。

这里先教大家一个简单的正则表达式
比如说我们想匹配一个网址http://www.xxxx.com,用正则表达式如何表达呢?
我们可以把pattern写为:

pattern = re.compile(r'http://www\..+\.com')

我们可以看到,括号内的字符串前面有一个r,这个r建议当成一个固定的格式加在每个正则表达式前防止计算机在编译的时候将正则表达式转义,此外,这个正则表达式中除了中间的…+.这一部分代替了之前的.xxxx.的部分之外其他的没有变化。实际上这个字符串按从左往右的顺序来看可以分解为:

(http://www)匹配前缀
(\.)对.进行转义
(.+)表示匹配任意个(0个除外)任意字符
(\.)对.进行转义
(com)匹配尾缀

首先我们来解释一下(.+):
在正则表达式中,实心点.表示匹配任意除换行符意外的字符,加号+表示重复一次或更多次所以实心点和加号配合在一起使用就可以匹配长度至少为1的任意字符串,这个在正则表达式的使用中十分常见。

好了,解释了上面的(.+)你应该可以想到为什么要对实心点.进行转义了,实心点是我们想要匹配的字符,但由于实心点这个字符十分特殊,它是在正则表达式中有特殊的含义,所以当你想要匹配它的时候就必须用反斜杠对其进行转义告诉计算机这个实心点是我想匹配的实心点,而不是正则表达式中表示匹配任意字符的那个实心点。类似地你可以推理出来当我们想要匹配加号的时候我们也要相应的加上反斜杠将其转义。

上面的例子其实已经可以帮你解决很多问题了,但是肯定会有很多的局限性,为了提高我们匹配字符串的准确程度,我们需要了解更多的正则表达式的匹配语句。下面是它们的一些例子:

匹配任意数字:\d
匹配任意单词的开头或结束:\b
匹配任意字母、数字、下划线或汉字:\w
匹配任意空白符(包括空格、制表符Tab、换行符、中文全角空格等):\s
匹配任意除换行符以外的字符:.

上面的都叫做元字符,元字符就是用来匹配字符和位置的

我们可以在python中稍微练习一下
练习一:提取字符串中的数字

import re

s = "asdfasfsa324r5h2hr32kj5248hoih2r234hr208"
pattern = re.compile(r'\d+')
ss = re.findall(pattern,s)
print(ss)

运行结果:

['324', '5', '2', '32', '5248', '2', '234', '208']

正好我们可以从这里解释一下re库中的findall函数,在上面的代码中出现了,findall,顾名思义,就是找出所有满足该模式的字符串,它最终的结果会以列表的形式呈现出来。

练习二:提取字符串中s开头的单词

import re

s = "Do you still send a suit to the student in your school?"
pattern = re.compile(r'\bs\w*\b')
ss = re.findall(pattern,s)
print(ss)

运行结果:

['still', 'send', 'suit', 'student', 'school']

这里解释一下*的意思:
*的意思就是前面的字符串重复零次或多次

差不多就先练这些,我们继续学习正则表达式中另一个非常重要的概念:限定符

限定符是什么呢?前面的加号就是一个限定符,限定符的作用就是把前面的元字符组织起来,表示这些元字符的重复次数的,常用的限定符有

*:表示重复零次或多次
+:表示重复一次或多次
?:表示重复零次或一次
{n}:表示重复n次
{n,}:表示重复n次或更多次
{n,m}:表示重复n次到m次

最简单的例子就是匹配qq号,比如说要匹配一个字符串中9位数的qq号我们可以用下面的代码:

import re

s = "tel:4564815,qq:616165165,tel:1813165,qq:164186165,tel:4789465"
pattern = re.compile(r'\d{9}')
ss = re.findall(pattern,s)
print(ss)

运行结果:

['616165165', '164186165']

再练习一个,找出一个字符串中所有四个字的词语:

import re

s = "儒雅随和,天皇驾到,宁配吗,难定了,芜湖,逼逼赖赖"
pattern = re.compile(r'\w{4}')
ss = re.findall(pattern,s)
print(ss)

运行结果:

['儒雅随和', '天皇驾到', '逼逼赖赖']

字符集合
当你想要匹配一些自己规定的字符作为元字符的时候,你可以用中括号[]将你选择的范围(字符集)括起来,比如说[abc]的意思就是匹配abc中的任意一个字符,除此之外还可以用[0-9]、[a-z]、[A-Z]等表示方法来表示范围。

反义的使用方法:
有时候需要查找出去某一类字符集之外的字符,比如说想查找出来数字意外包含其他任意字符的情况,这时候就要用到反义。

\W:匹配任意不是字母、数字、下划线】汉字的字符
\S:匹配任意不是空白字符的字符
\D:匹配任意不是数字的字符
\B:匹配不是单词开头或结束的位置
[^a]:匹配除了a以外的任意字符
[^abcd]:匹配除了a、b、c、d以外的任意字符
[^(abc|123)]:匹配除了1、2、3或a、b、c以外的任意字符

懒惰模式
我们之前一直没有遇到一个问题,那就是,有时候一些字符串我们需要区分开来,比如说当我们想匹配以p开头n结尾的单词的时候,python,pythonaaan,pythonpython都是可返回的对象,一般来说如果不加任何说明,正则表达式就会一直勤奋工作,也就是当它找到满足条件的字符串后它也不会停下,依然继续往下搜索,如果想让它“偷懒”的话,我们需要加上一个问号作为结尾,告诉它点到为止,不要再继续往下找了。

import re

s = "pythonpythonpython"
pattern1 = re.compile(r'p.+n')
pattern2 = re.compile(r'p.+?n')
s1 = re.search(pattern1,s)
s2 = re.search(pattern2,s)
print(s1)
print(s2)

运行结果:

<re.Match object; span=(0, 18), match='pythonpythonpython'>
<re.Match object; span=(0, 6), match='python'>

以上就是这篇文章所讲的正则表达式的使用方法了,熟练使用正则表达式的最好方法就是多在爬虫的过滤步骤中使用正则表达式做搜索工具,下一篇将会讲解BeautifulSoup的使用方法。

  • 点赞
  • 收藏
  • 分享
  • 文章举报
yuのblog 发布了2 篇原创文章 · 获赞 0 · 访问量 26 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: