爬虫03:正则解析

爬虫•目录 爬虫•类别


解析模块

数据的分类

  • 结构化数据
    固定格式 HTML JSON XML

      <a>
          <b>
          </b>
      </a>
    
  • 非结构化数据
    图片 音频 视频

    一般存储为二进制(wb)

正则解析模块re

  • rList = re.findall(r'表达式', '字符串', re.S)
  • 推荐写法
    1.创建编译对象
      p = re.compile(r’’, re.S)
    2.进行字符串匹配
      rList = p.findall(html)
  • 元字符
    .:匹配任意1个字符(不包括\n)
    \d:1个数字
    \s:空白字符
    \S:非空白字符
    [ ]:包含[]内容 [\s\S]匹配任意一个字符
    \w:普通字符 字母数字下划线
    \W:特殊字符

    *:0次或N次
    +:1次或N次
    ?:0次或1次
    {m}:m次

  • 贪婪匹配,非贪婪匹配
    1.贪婪匹配(.*) 在表达式匹配成功的前提下,尽可能多的匹配*
    2.非贪婪匹配(.*?) 在表达式匹配成功的前提下,尽可能少的匹配*

      import re
    
      html = '''
      <div><p>汉皇重色思倾国</p></div>
      <div><p>御宇多年求不得</p></div>
      '''
      #贪婪.*
      p = re.compile(r'<div><p>.*</p></div>', re.S)
      rList = p.findall(html)
      print(rList) 
      #Out:['<div><p>汉皇重色思倾国</p></div>\n<div><p>御宇多年求不得</p></div>']
    
      #非贪婪.*?
      p = re.compile(r'<div><p>.*?</p></div>', re.S)
      rList = p.findall(html)
      print(rList)
      #Out:['<div><p>汉皇重色思倾国</p></div>', '<div><p>御宇多年求不得</p></div>']
    
  • 正则分组

      s = 'a b c d'
      p1 = re.compile('\w+\s+\w+')
      print(p1.findall(s))
      #Out:['a b', 'c d']
    
      p2 = re.compile('\w+\s+(\w+)')
      print(p2.findall(s))
      #Out:['b', 'd']
    
      p3 = re.compile('(\w+)\s+(\w+)')
      print(p3.findall(s))
      #Out:[('a', 'b'), ('c', 'd')]
    

    按照不带括号匹配,返回括号内容,不加括号认为括号最大,多个分组(括号),以元组形式显示

正则案例

import re

html='''
<div class="financial">
  <p class="name">
    <a title="Stata"></a>
  </p>

  <p class="contents">
    This is a basic course.
  </p>  
</div>

<div class="financial">
  <p class="name">
    <a title="Linear Algebra"></a>
  </p>

  <p class="contents">
    It's just an enhancement course.
  </p>  
</div>
'''
p = re.compile(r'<div class="(.*?)".*?title="(.*?)".*?"contents".*?\s+(.*?)\n.*?</div>', re.S)
s = p.findall(html)
print(s)
#Out:[('financial', 'stata', 'This is a basic course.'), ('financial', 'Linear Algebra', "It's just an enhancement course.")]
for str in s:
    print('='*20)
    print('Name is :', str[1])
    print('Describe :', str[2])
#Out:====================
#Out:Name is : stata
#Out:Describe : This is a basic course.
#Out:====================
#Out:Name is : Linear Algebra
#Out:Describe : It's just an enhancement course.

CSV解析模块

CSV模块流程

  • 导入
    import csv
  • 打开CSV文件
    with open('xxx.csv', 'w') as f:
  • 初始化写入对象
    writer = csv.writer(f)
  • 写入数据
    writer.writerow([])
  • EX:
    `python
    import csv

#newline=’’表示换行为空,保证新写入数据不会出现空行
with open(‘price.csv’, ‘w’, newline=’’) as f:

# 初始化对象
writer = csv.writer(f)
#利用写入对象写入数据
writer.writerow(['open','12.01'])
writer.writerow(['close','13.01'])

### 案例
猫眼电影top100榜单
>* 1、网址 :猫眼电影 - 榜单 - top100榜
* 2、目标 :电影名称、主演、上映时间
* 3、步骤
    * 1、找URL规律
        第1页:https://maoyan.com/board/4?offset=0
        第2页:https://maoyan.com/board/4?offset=10
        第n页:offset=(n-1)*10
    * 2、写正则表达式
        `'<div class="movie-item-info">.*?title="(.*?)".*?class="star">(.*?)</p>.*?class="releasetime">(.*?)</p>',re.S`

```python
import urllib.request
import re
import csv
import time

class MaoyanSpider(object):
    def __init__(self):
        self.baseurl = 'https://maoyan.com/board/4?offset='
        self.headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36'}

    def getPage(self, url):
        '''获取页面函数
        '''
        req = urllib.request.Request(url, headers=self.headers)
        res = urllib.request.urlopen(req)
        html = res.read().decode('utf-8')
        self.parePage(html)

    def parePage(self, html):
        '''解析函数
        '''
        p = re.compile('<div class="movie-item-info">.*?title="(.*?)".*?<p class="star">\s*(.*?)\s*</p >.*?<p class="releasetime">(.*?)', re.S)
        rList = p.findall(html)
        self.writeCsv(rList)

    def writeCsv(self, rList):
        '''保存数据
        '''
        with open('maoyan.csv', 'a', newline='', encoding='utf-8') as f:
            writer = csv.writer(f)
            for rt in rList:
                info = list(rt)
                writer.writerow(info)


    def workOn(self):
        for pg in range(0, 100, 10):
            url = self.baseurl + str(pg)
            self.getPage(url)
            time.sleep(2)
        print('successful')


if __name__ == '__main__':
    spider = MaoyanSpider()
    spider.workOn()

博主个人能力有限,错误在所难免.
如发现错误请不要吝啬,发邮件给博主更正内容,在此提前鸣谢.
Email: JentChang@163.com (来信请注明文章标题,如果附带链接就更方便了)
你也可以在下方的留言板留下你宝贵的意见.


上一篇
爬虫04:数据持久存储 爬虫04:数据持久存储
爬虫•目录 爬虫•类别 Mongo数据库pymongo 1、连接对象 conn = pymongo.MongoClient(‘IP’,27017) 2、库对象 db = conn[‘库名’] 3、集合对象 myset = db[‘集
2019-01-22
下一篇
爬虫02:请求及案例 爬虫02:请求及案例
爬虫•目录 爬虫•类别 1.GET1特点值在url后面 以键值的形式追加在后面  2案例上节案例 2.POST(在Request()中添加data参数)data参数urllib.request.Request(url, data=data
2019-01-22
目录