python爬虫 正则表达式使用技巧及爬取个人博客的实例讲解
|
这篇博客是自己《数据挖掘与分析》课程讲到正则表达式爬虫的相关内容,主要简单介绍Python正则表达式爬虫,同时讲述常见的正则表达式分析方法,最后通过实例爬取作者的个人博客网站。希望这篇基础文章对您有所帮助,如果文章中存在错误或不足之处,还请海涵。真的太忙了,太长时间没有写博客了,抱歉~ 一.正则表达式 正则表达式(Regular Expression,简称Regex或RE)又称为正规表示法或常规表示法,常常用来检索、替换那些符合某个模式的文本,它首先设定好了一些特殊的字及字符组合,通过组合的“规则字符串”来对表达式进行过滤,从而获取或匹配我们想要的特定内容。它具有灵活、逻辑性和功能性非常的强,能迅速地通过表达式从字符串中找到所需信息的优点,但对于刚接触的人来说,比较晦涩难懂。 1.re模块 Python通过re模块提供对正则表达式的支持,使用正则表达式之前需要导入该库。 import re import re其基本步骤是先将正则表达式的字符串形式编译为Pattern实例,然后使用Pattern实例处理文本并获得一个匹配(Match)实例,再使用Match实例获得所需信息。常用的函数是findall,原型如下: findall(string[,pos[,endpos]]) | re.findall(pattern,string[,flags]) 该函数表示搜索字符串string,以列表形式返回全部能匹配的子串。 其中参数re包括三个常见值: (1)re.I(re.IGNORECASE):忽略大小写(括号内是完整写法) (2)re.M(re.MULTILINE):允许多行模式 (3)re.S(re.DOTALL):支持点任意匹配模式 Pattern对象是一个编译好的正则表达式,通过Pattern提供的一系列方法可以对文本进行匹配查找。Pattern不能直接实例化,必须使用re.compile()进行构造。 2.complie方法 re正则表达式模块包括一些常用的操作函数,比如complie()函数。其原型如下: compile(pattern[,flags] ) 该函数根据包含正则表达式的字符串创建模式对象,返回一个pattern对象。参数flags是匹配模式,可以使用按位或“|”表示同时生效,也可以在正则表达式字符串中指定。Pattern对象是不能直接实例化的,只能通过compile方法得到。 简单举个实例,使用正则表达式获取字符串中的数字内容,如下所示: >>> import re >>> string="A1.45,b5,6.45,8.82" >>> regex = re.compile(r"d+.?d*") >>> print regex.findall(string) ['1.45','5','6.45','8.82'] >>> 3.match方法 match方法是从字符串的pos下标处起开始匹配pattern,如果pattern结束时已经匹配,则返回一个Match对象;如果匹配过程中pattern无法匹配,或者匹配未结束就已到达endpos,则返回None。该方法原型如下: match(string[,endpos]]) | re.match(pattern,flags]) 参数string表示字符串;pos表示下标,pos和endpos的默认值分别为0和len(string);参数flags用于编译pattern时指定匹配模式。 4.search方法 search方法用于查找字符串中可以匹配成功的子串。从字符串的pos下标处起尝试匹配pattern,如果pattern结束时仍可匹配,则返回一个Match对象;若无法匹配,则将pos加1后重新尝试匹配;直到pos=endpos时仍无法匹配则返回None。 函数原型如下: search(string[,endpos]]) | re.search(pattern,flags]) 参数string表示字符串;pos表示下标,pos和endpos的默认值分别为0和len(string));参数flags用于编译pattern时指定匹配模式。 5.group和groups方法 group([group1,…])方法用于获得一个或多个分组截获的字符串,当它指定多个参数时将以元组形式返回。groups([default])方法以元组形式返回全部分组截获的字符串,相当于调用group(1,2,…last)。default表示没有截获字符串的组以这个值替代,默认为None。 二.正则表达式抓取网络数据常见方法 在第三小节作者将介绍常用的正则表达式抓取网络数据的一些技巧,这些技巧都是作者自然语言处理和数据抓取实际编程中的总结,可能不是很系统,但是也能给读者提供一些抓取数据的思路以及解决实际的一些问题。 1.抓取标签间的内容 HTML语言是采用标签对的形式来编写网站的,包括起始标签和结束标签,比如<head></head>、<tr></tr>、<script><script>等。下面讲解抓取标签对之间的文本内容。 (1) 抓取title标签间的内容 首先爬取网页的标题,采用的正则表达式为'<title>(.*?)</title>',爬取百度标题代码如下: # coding=utf-8 import re import urllib url = "http://www.baidu.com/" content = urllib.urlopen(url).read() title = re.findall(r'<title>(.*?)</title>',content) print title[0] # 百度一下,你就知道 代码调用urllib库的urlopen()函数打开超链接,并借用正则表达式库中的findall()函数寻找title标签间的内容,由于findall()函数获取所有满足该正则表达式的文本,故输出第一个值title[0]即可。下面是获取标签的另一种方法。 pat = r'(?<=<title>).*?(?=</title>)' ex = re.compile(pat,re.M|re.S) obj = re.search(ex,content) title = obj.group() print title # 百度一下,你就知道 (2) 抓取超链接标签间的内容 在HTML中,<a href=URL></a>用于标识超链接,test03_08.py文件用于获取完整的超链接和超链接<a>和</a>之间的内容。 # coding=utf-8 import re import urllib url = "http://www.baidu.com/" content = urllib.urlopen(url).read() #获取完整超链接 res = r"<a.*?href=.*?</a>" urls = re.findall(res,content) for u in urls: print unicode(u,'utf-8') #获取超链接<a>和</a>之间内容 res = r'<a .*?>(.*?)</a>' texts = re.findall(res,content,re.S|re.M) for t in texts: print unicode(t,'utf-8') 输出结果部分内容如下所示,这里如果直接输出print u或print t可能会乱码,需要调用函数unicode(u,'utf-8')进行转码。 #获取完整超链接 <a href="http://news.baidu.com" rel="external nofollow" rel="external nofollow" name="tj_trnews" class="mnav">新闻</a> <a href="http://www.hao123.com" rel="external nofollow" rel="external nofollow" name="tj_trhao123" class="mnav">hao123</a> <a href="http://map.baidu.com" rel="external nofollow" rel="external nofollow" name="tj_trmap" class="mnav">地图</a> <a href="http://v.baidu.com" rel="external nofollow" rel="external nofollow" name="tj_trvideo" class="mnav">视频</a> ... #获取超链接<a>和</a>之间内容 新闻 hao123 地图 视频 ... (3) 抓取trtd标签间的内容 网页中常用的布局包括table布局或div布局,其中table表格布局中常见的标签包括tr、th和td,表格行为tr(table row),表格数据为td(table data),表格表头th(table heading)。那么如何抓取这些标签之间的内容呢?下面代码是获取它们之间内容。 假设存在HTML代码如下所示: <html> <head><title>表格</title></head> <body> <table border=1> <tr><th>学号</th><th>姓名</th></tr> <tr><td>1001</td><td>杨秀璋</td></tr> <tr><td>1002</td><td>严娜</td></tr> </table> </body> </html> 则爬取对应值的Python代码如下:
# coding=utf-8
import re
import urllib
content = urllib.urlopen("test.html").read() #打开本地文件
#获取<tr></tr>间内容
res = r'<tr>(.*?)</tr>'
texts = re.findall(res,re.S|re.M)
for m in texts:
print m
#获取<th></th>间内容
for m in texts:
res_th = r'<th>(.*?)</th>'
m_th = re.findall(res_th,m,re.S|re.M)
for t in m_th:
print t
#直接获取<td></td>间内容
res = r'<td>(.*?)</td><td>(.*?)</td>'
texts = re.findall(res,re.S|re.M)
for m in texts:
print m[0],m[1]
输出结果如下,首先获取tr之间的内容,然后再在tr之间内容中获取<th>和</th>之间值,即“学号”、“姓名”,最后讲述直接获取两个<td>之间的内容方法。 >>> <th>学号</th><th>姓名</th> <td>1001</td><td>杨秀璋</td> <td>1002</td><td>严娜</td> 学号 姓名 1001 杨秀璋 1002 严娜 >>> 2.抓取标签中的参数 (1) 抓取超链接标签的URL HTML超链接的基本格式为“<a href=URL>链接内容</a>”,现在需要获取其中的URL链接地址,方法如下: # coding=utf-8 import re content = ''' <a href="http://news.baidu.com" rel="external nofollow" rel="external nofollow" name="tj_trnews" class="mnav">新闻</a> <a href="http://www.hao123.com" rel="external nofollow" rel="external nofollow" name="tj_trhao123" class="mnav">hao123</a> <a href="http://map.baidu.com" rel="external nofollow" rel="external nofollow" name="tj_trmap" class="mnav">地图</a> <a href="http://v.baidu.com" rel="external nofollow" rel="external nofollow" name="tj_trvideo" class="mnav">视频</a> ''' res = r"(?<=href=").+?(?=")|(?<=href=').+?(?=')" urls = re.findall(res,re.I|re.S|re.M) for url in urls: print url 输出内容如下: >>> http://news.baidu.com http://www.hao123.com http://map.baidu.com http://v.baidu.com >>> (2) 抓取图片超链接标签的URL (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
