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

系统 1065 0

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
            
          

 

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
            
          

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

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

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

◆string;待匹配字符串

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

            
              ls = re.findall(r'[1-9]\d{5}','bit100081 tsu100084')
print ls   #['100081', '100084']
            
          

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']
            
          

 

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
            
          

 

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
            
          

Re库的另一种等价用法:

            
              pat = re.compile(r'[1-9]\d{5}')
res = pat.search('bit 100081')

regex = re.compile(pattern, flags=0)
            
          

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

◆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)
            
          

 

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

            
              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()
            
          

 


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论