Advertisement

Python网络爬虫与信息提取——正则表达式

阅读量:

Python网络爬虫与信息提取——正则表达式

正则表达式的语法

正则表达式的常用操作符
操作符 说明 实例
. 表示任何单个字符
[] 字符集,对单个字符给出取值范围 [abc]表示a、 b、c, [a-z]表示a到z单个字符
[^ ] 非字符集,对单个字符给出排除范围 [^ abc]表示非a或b或c的单个字符
* 前一个字符0次或无限次扩展 abc*表示ab、abc、abcc、 abccc等
+ 前一个字符1次或无限次扩展 abc+表示abc、abcc、 abccc等
? 前一个字符0次或1次扩展 abc?表示ab、abc
左右表达式任意一个 abc def表示abc、def
{m} 扩展前一个字符m次 ab{2}c表示abbc
{m,n} 扩展前一个字符m至n次(含n) ab{1,2}c表示abc、 abbc
^ 匹配字符串开头 ^abc表示abc且在一 个字符串的开头
$ 匹配字符串结尾 abc$表示abc且在一个 字符串的结尾
() 分组标记,内部只能使用 操作符 (abc)表示abe, (abcldef)表示abe、 def
\d 数字,等价于[0-9]
\w 单词字符,等价于[A-Za-z0-9_]

Re库的基本使用

raw string类型(原生字符串类型)

1.用原生字符串类型不用专义,如r'\d+\w{3}'

2.不用原生字符串类型,如‘\ d+\ w{3}’

Re库主要功能函数
函数 说明
re.search() 在一个字符串中搜索匹配正则表达式的第一个位置, 返回match对象
re.match() 从一个字符串的开始位置起匹配正则表达式,返回match对象
re.findall() 搜索字符串,以列表类型返回全部能匹配的子串
re.split() 将一个字符串按照正则表达式匹配结果进行分割,返回列表类型
re.finditer() 搜索字符串,返回一个匹配结果的选代类型,每个迭代元素是match对象
re.sub() 在一个字符串中替换所有匹配正则表达式的子串,返回替换后的字符串

1.re.search(pattern, string, flags=0)

在一个字符串中搜索匹配正则表达式的第一个 位置,返回match对象。

◆pattern:正则表达式的字符串或原生字符串表示

◆string:待匹配字符串

◆flags:正则表达式使用时的控制标记

flags:正则表达式使用时的控制标记
常用标记 说明
re.I re.IGNORECAS 忽略正则表达式的大小写,[A-Z]能够匹配小写字符
re.M re.MULTILINE 正则表达式中的^操作符能够将给定字符串的每行当作匹配开始
re.S re.DOTALL 正则表达式中的操作符能够匹配所有字符,默认匹配除换行外的所有字符
复制代码
 import re

    
 match = re.search(r'[1-9]\d{5}','bat 100081')
    
 if match:
    
     print match.group(0)   ##100081
    
    
    
    
    AI写代码

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

从一个字符串的开始位置起匹配正则表达式,返回match对象。

◆pattern:正则表达式的字符串或原生字符串表示

◆string:待匹配字符串

◆flags: 正则表达式使用时的控制标记

复制代码
 import re

    
 match = re.match(r'[1-9]\d{5}','bit 100081')
    
 if match:
    
     print match.group(0)
    
  
    
 match = re.match(r'[1-9]\d{5}','100081 bit')
    
 if match:
    
     print match.group(0)  #100081
    
    
    
    
    AI写代码

3.re.findall(pattern, string, flags=0)

搜索字符串,以列表类型返回全部能匹配的子串。

◆pattern:正则表达式的字符串或原生字符串表示

◆string;待匹配字符串

◆flags:正则表达式使用时的控制标记

复制代码
 ls = re.findall(r'[1-9]\d{5}','bit100081 tsu100084')

    
 print ls   #['100081', '100084']
    
    
    
    
    AI写代码

4.re.split(pattern, string, maxsplit=0, flags=0)

将一个字符串按照正则表达式匹配结果进行分割,返回列表类型。

◆pattern:正则表达式的字符串或原生字符串表示

◆string:待匹配字符串

◆maxsplit:最大分割数,剩余部分作为最后一个 元素输出

◆flags:正则表达式使用时的控制标记

复制代码
 print re.split(r'[1-9]\d{5}','bit100081 tsu100084')

    
 #['bit', ' tsu', '']
    
 print re.split(r'[1-9]\d{5}','bit100081 tsu100084', maxsplit=1)
    
 #['bit', ' tsu100084']
    
    
    
    
    AI写代码

5.re.finditer(pattern, string, flags=0)

搜索字符串,返回一个匹配结果的迭代类型,每个迭代元素是match对象。

◆pattern:正则表达式的字符串或原生字符串表示

◆string:待匹配字符串

◆flags:正则表达式使用时的控制标记

复制代码
 for m in re.finditer(r'[1-9]\d{5}','bit100081 tsu100084'):

    
     if m:
    
     print m.group(0)
    
 #100081
    
 #100084
    
    
    
    
    AI写代码

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

在一个字符串中替换所有匹配正则表达式的子串,返回替换后的字符串。

◆pattern: 正则表达式的字符串或原生字符串表示

◆repl:替换匹配字符串的字符串

◆string:待匹配字符串

◆count:匹配的最大替换次数

◆flags:正则表达式使用时的控制标记

复制代码
 print re.sub(r'[1-9]\d{5}',':zipcode','bit100081 tsu100084')

    
 #bit:zipcode tsu:zipcode
    
    
    
    
    AI写代码

Re库的另一种等价用法:

复制代码
 pat = re.compile(r'[1-9]\d{5}')

    
 res = pat.search('bit 100081')
    
  
    
 regex = re.compile(pattern, flags=0)
    
    
    
    
    AI写代码

将正则表达式的字符串形式编译成正则表达式对象

◆pattern:正则表达式的字符串或原生字符串表示

◆flags:正则表达式使用时的控制标记

Re库的match对象

match对象的属性
属性 说明
.string 待匹配的文本
.re 匹配时使用的pattern对象(正则表达式)
.pos 正则表达式搜索文本的开始位置
.endpos 正则表达式搜索文本的结束位置
Match对象的方法
方法 说明
.group(0) 获得匹配后的字符串
.start() 匹配字符串在原始字符串的开始位置
.end() 匹配字符串在原始字符串的结束位置
.span() 返回(.start(), .end())
复制代码
 m = re.search(r'[1-9]\d{5}','bit100081 tsu100084')

    
 print m.string  #bit100081 tsu100084
    
 print m.re  #<_sre.SRE_Pattern object at 0x10854d7b0>
    
 print m.pos  #0
    
 print m.endpos   #19
    
 print m.group(0)  #100081
    
 print m.start()  #3
    
 print m.end()   #9
    
 print m.span()   #(3,9)
    
    
    
    
    AI写代码

实例:淘宝商品信息定向爬虫

复制代码
 def gethtmltext(url):

    
     try:
    
     r = requests.get(url, timeout=30)
    
     r.raise_for_status()
    
     r.encoding = r.apparent_encoding
    
     return r.text
    
     except:
    
     return ""
    
  
    
 def parsepage(ilt, html):
    
     try:
    
     plt = re.findall(r'\"view_price\"\:\"[\d\.]*\"', html)
    
     tlt = re.findall(r'\"raw_title\"\:\".*?\"', html)
    
     for i in range(len(plt)):
    
         price = eval(plt[i].split(':')[1])
    
         title = eval(tlt[i].split(':')[1])
    
         ilt.append([price, title])
    
     except:
    
     print ""
    
  
    
 def printgoodslist(ilt):
    
     tplt = "{:4}\t{:8}\t{:16}"
    
     print tplt.format("序号", "价格", "商品名称")
    
     count = 0
    
     for g in ilt:
    
     print tplt.format(count, g[0], g[1])
    
  
    
 def main():
    
     goods = '书包'
    
     depth = 2
    
     start_url = 'https://s.taobao.com/search?q=' + goods
    
     infolist = []
    
     for i in range(depth):
    
     try:
    
         url = start_url + '&s=' + str(44+i)
    
         html = gethtmltext(url)
    
         parsepage(infolist, html)
    
     except:
    
         continue
    
     printgoodslist(infolist)
    
  
    
 main()
    
  
    
  
    
 实例:股票数据定向爬虫
    
  
    
  
    
 def gethtmltext(url):
    
   try:
    
     r = requests.get(url, timeout=30)
    
     r.raise_for_status()
    
     r.encoding = r.apparent_encoding
    
     return r.text
    
   except:
    
     return ""
    
  
    
 def getstocklist(lst, stockurl):
    
   html = gethtmltext(stockurl)
    
   soup = BeautifulSoup(html, 'html.parser')
    
   a = soup.find_all('a')
    
   for i in a:
    
     try:
    
       href = i.attrs['href']
    
       lst.append(re.findall(r"[s][hz]\d{6}", href))
    
     except:
    
       continue
    
  
    
 def getstockinfo(lst, stockurl, fpath):
    
   for stock in lst:
    
     url = stockurl + stock + '.html'
    
     html = gethtmltext(url)
    
     try:
    
       if html == "":
    
     continue
    
       infodict = []
    
       soup = BeautifulSoup(html, 'html.parser')
    
       stockinfo = soup.find('div', attrs={'class':'stock-bets'})
    
  
    
       name = stockinfo.find_all(attrs={'class':'bets-name'})[0]
    
       infodict.update({'股票名称':name.text.split()[0]})
    
  
    
       keylist = stockinfo.find_all('dt')
    
       valuelist = stocklist.find_all('dd')
    
       for i in range(len(keylist)):
    
     key = keylist[i].text
    
     val = valuelist[i].text
    
     infodict[key] = val
    
  
    
       with open(fpath, 'a', encoding='utf-8') as f:
    
     f.write(str(infodict) + '\n')
    
  
    
 def main():
    
   stock_list_url = 'http://quote.eastmoney.com/stocklist.html'
    
   stock_info_url = 'https://gupiao.baidu.com/stock'
    
   output_file = './baiduinfostock.txt'
    
   slist = []
    
   getstocklist(slist, stock_list_url)
    
   getstockinfo(slist, stock_info_url, output_file)
    
  
    
 main()
    
    
    
    
    AI写代码

全部评论 (0)

还没有任何评论哟~