首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

python爬虫:散文网站内容抓取实战案例附源码

东尧爱分享

这是东尧每天一篇文章的第33天

东尧写文章的目标:分享东尧的经验和思考,帮你获取物质和精神两方面幸福。

昨天我们已经讲到了正则表达式一些常用的语法规则,那么今天东尧就用实例为大家讲解正则表达式在python中的强大用处。

1

正则表达式常用函数和方法

在python中使用正则表达式需要导入正则表达式模块(re)这个是python内置的模块,因此不需要安装,但是需要注意的是我们给文件命名的时候不要使用这个名字,否则就会造成模块名称冲突导致用不了。

re中的flag参数及其含义

1.忽略大小写(常用)

I = IGNORECASE = sre_compile.SRE_FLAG_IGNORECASE

2.\w, \W, \b, \B等是否生效取决于当前的系统环境(其实没啥用)

L = LOCALE = sre_compile.SRE_FLAG_LOCALE

3.匹配Unicode字符串,主要是对与非ASCII码字符串来讲的,因为python2默认的字符串都是ASCII编码的,所以模式\w+能匹 配的都是ASCII字符,要想让\w+匹配Unicode字符,就可以设置这个flag

U = UNICODE = sre_compile.SRE_FLAG_UNICODE

4.多行匹配,主要就是当匹配行首(^)或行尾($)的时候,如果不使用多行匹配的话,对于多行的文本是不能匹配成功的

M = MULTILINE = sre_compile.SRE_FLAG_MULTILINE

5.让点号(.)也代表换行(常用)

S = DOTALL = sre_compile.SRE_FLAG_DOTALL

6.忽略表达式模式中的空白字符和注释

X = VERBOSE = sre_compile.SRE_FLAG_VERBOSE

2

爬虫实战案例

以散文网“https://www.sanwen.net/sanwen/”为例,东尧将演示如何用正则表达式提取散文网上的文章标题、URL等内容。示例网页内容包含了文章标题,文章url等内容,原始网站内容截图如下:

接下来就是使用python爬虫来抓取网页内容了:

1

导入模块

re模块:python内置的正则表达式模块

requests模块:http请求模块

urllib.request:主要用到里面的headers模拟浏览器请求

2

模拟浏览器请求

有些网站设置了反爬机制,也就是说网站服务器会通过User-Agent的值来判断是否是浏览器发出的请求。当我们用python爬虫去抓取内容时,如果不设置User-Agent的值来模拟浏览器请求,那么就可能会被拒绝访问网站,也就抓取不到内容了。

所以一般在做网络爬虫时都会用urllib.request模块中的headers方法来模拟浏览器请求,让网站服务器对我们的爬虫开放。

headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'}

req = urllib.request.Request('https://www.sanwen.net/sanwen/',headers=headers)

# html存入了整个网页内容

html = requests.get('https://www.sanwen.net/sanwen/')

html = html.text

3

获取网页内容

使用requests模块的get方法,将网页内容获取到自定义变量中。这里需要注意的是,requests返回的是一个response对象,其存储了服务器响应的内容,如果我们要使用其中的内容,还需要将其用text方法对响应的文本编码进行解码(注意看下图两个html的区别,第一个是response对象,第二个是实际的网页内容)。

4

使用正则表达式匹配网页标题(title)

通过对源代码的观察我们发现,需要的网页标题title是放置在之间的文本内容,那这个时候就需要用到正则表达式来匹配其中的内容了:'(.*?)'。将需要提取出来的内容用括弧进行分组,方便后面提取分组内容,不需要的内容用“.*?”进行过滤就好。

这里可能有的同学会问,问什么要用“.*?”而不用“.*”来匹配呢?这是因为“.*”是贪婪模式,这个时候会尽可能多的匹配,而加了?则是尽可能少的匹配。打个比方,现在有文本如下:

经典散文_经典文章欣赏_散文网经典散文_经典文章欣赏_散文网经典散文_经典文章欣赏_散文网

我们可以看到,里面包含了3对组合,也就是说有3个标题,那么这时候我们用“.*”的匹配结果就会是从第一个开始,直到最后一个结束,全部都被匹配进去了:

而加了?的话,就会按对的形式,一个一个的匹配出来,结果如下:

所以我们在进行匹配的时候,一定要注意贪婪模式和非贪婪模式的区别,如果拿不准匹配结果,可以将网页内容复制到sublime中先试着写正则表达式匹配试下,成功了才将正则表达式写入到python中。

compile方法:

compile方法是预先编译正则表达式的匹配模式,然后生成一个缓存,这样在之后的匹配中就可以直接使用这个缓存,而不需要每次匹配都重新编译,从而加快速度。

一般情况下只有当一个正则表达式被重复使用多次的时候才需要事先使用compile方法编译,如果只是使用一次就不需要了。请看下图中使用compile方法事先编译和不使用compile方法的区别:

group()与groups()的区别:

groups方法返回全部匹配成功的子组,返回的是元组。group方法返回的是全部匹配对象,如果我们只要其中的子组,就需要加上参数。请看下图中两者的结果对比:

5

使用正则表达式匹配文章标题(article_title)

正则表达式的写法与刚才并无二致,这里要给大家介绍的是findall方法:用findall方法匹配所有符合要求的字符串。findall方法返回的是一个列表。示例如下:

那么我们就可以使用findall方法来匹配网页中所有符合的内容存入至列表中,然后通过for循环将列表内容提取出来:

6

使用正则表达式匹配文章url(article_url)

可以看到直接获取列表中文章url这里得到的结果是相对路径,那么我们就需要使用一些方法来将路径补充完整。这里东尧为大家介绍两种方法:

第一种是列表推导式:

第二种是用正则表达式的sub或subn方法进行字符串的替换:

7

关于大小写匹配和换行匹配

有时候我们在匹配时可能会犯大小写不分的错误,那么如何在匹配时不用区分大小写呢?re模块中的flag参数I就是用作忽略大小写匹配的,用法如下:

有时候某些内容在匹配时涉及到换行,而“.”只能匹配除换行符以外的所有字符,如果要连换行符也一同匹配进去,就需要用到re模块中的flag参数S。用法如下:

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180510G0YYQO00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券