3.数据解析之re解析

数据解析

1. 数据解析概述

1.1 数据解析方式

  1. re 解析
  2. bs4 解析
  3. xpath 解析
  4. pyquery 解析

1.2 数据解析原理

解析的局部的文本内容都会在标签之间或标签对应的属性中进行存储

  • 进行指定标签的定位
  • 标签或者标签对应的属性中存储的数据值进行提取(解析)

1.3 数据解析爬虫流程

  • 指定 url

  • 发起请求 get/post

  • 获取相应数据

  • 数据解析

  • 持久化存储

2. re 解析

2.1 re 基础

2.1.1 正则表达式基础

正则表达式:对字符串操作的一种逻辑公式,一般用来对字符串进行匹配和筛选

常用元字符

代码说明
.匹配 除换行符以外的其他所有字符
\w匹配 数字,字母,下划线
\s匹配 任意的空白符
\d匹配 数字
\n匹配 换行符
\t匹配 制表符
\b匹配 单词的开始或结束
^匹配 字符串的开始(在集合字符里[^a]表示非(不匹配)的意思
$匹配 字符串的结束

常用反义字符

代码/语法说明
\W匹配 任意不是字母,数字,下划线,汉字的字符
\D匹配 任意非数字的字符
\S匹配 任意不是空白符的字符
\B匹配 不是单词开头或结束的位置
a|b匹配 a 或者 b
( )匹配()内的内容,也表示一个组
[…]匹配 字符组中的字符
[^…]匹配 除了字符组中的所有字符

常用限定词/量词

代码/语法说明
*重复 0 次或者更多次
+重复 1 次或者更多次
重复 0 次或者 1 次
{n}重复 n 次
{n, }重复 n 次或者更多次
{m, n}重复 n 次到 m 次
2.1.2 惰性匹配和贪婪匹配
  • 贪婪匹配:正则表达式中包含重复的限定符时,通常的行为是匹配尽可能多的字符。
    • ?,*,+,{}都属于贪恋匹配
  • 懒惰匹配:有时候需要匹配尽可能少的字符
    • 在上述量词后再加一个 ? 则属于惰性匹配 eg:*?,+?
2.1.3 匹配模式
  • re.I: 忽略大小写
  • re.M: 多行匹配
  • re.S:单行匹配 让 . 可以匹配换行符

2.2re 模块常用函数

2.2.1 compile 方法

根据包含正则表达式的字符串创建模式对象,返回一个pattern对象

  • re.compile (pattern = “flags”) flags 表示匹配模式
  • re.compile (r"flags")
2.2.2 findall 函数
  • re.findall (parttern,string)
  • pattern.findall (string)

表示搜索字符串,然后以列表 形式返回全部匹配的子字符串

2.2.3 finditer 函数
  • re.finditer (parttern,string)
  • pattern.finditer (string)

表示搜索字符串,然后以迭代器 形式返回全部匹配的子字符串

2.2.4 match 方法和 search 方法

共同点:

  • 两种方法都用于匹配子字符串
  • 两种方法都返回 match 对象

不同点:

  • match 仅从第一个字符开始匹配,匹配失败返回 None
  • search 会逐个开始匹配,直到匹配成功或失败 即 search 可以匹配包含的第一次出现的子字符串

re.match (pattren , 子字符串,匹配模式)

re.search (pattern , 字符串,匹配模式)

2.2.5 group()

用于返回迭代器中的数据

2.3 re 爬虫实战

思路

  • 拿到页面源代码
  • 编写正则,提取页面数据
  • 保存数据
2.3.1 需求 爬取 豆瓣Top 250数据

csv文件:文件中的数据以 “ , ” 隔开

使用时需要导入 csv模块

import re
import requests
import csv

url = "https://movie.douban.com/top250"
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36"
}

fp = open("豆瓣top250.csv","w",encoding="utf-8")
obj = re.compile(r'<div class="item">.*?<em class="">(?P<num>.*?)</em>'
                 r'.*?<span class="title">(?P<title>.*?)</span>'
                 r'.*?<p class="">(?P<direct>.*?)&nbsp'
                 r'.*?<br>(?P<years>.*?)&nbsp'
                 r'.*?<span class="rating_num" property="v:average">(?P<score>.*?)</span>'
                 r'.*?<span>(?P<number>.*?)</span>'
                 r'.*?<span class="inq">(?P<comment>.*?)</span>', re.S)
for i in range(10):
    start = i *25
    param = {
        "start":start
    }
    resp = requests.get(url=url,headers=headers,params=param)
    page_source = resp.text

    # print(page_source)
    result = obj.finditer(page_source)
    for item in result:
        num = item.group("num")
        title = item.group("title")
        score = item.group("score")
        direct = item.group("direct").strip()
        years = item.group("years").strip()
        number = item.group("number")
        comment = item.group("comment")
        fp.write(f"{num},{title},{score},{direct},{years},{number},{comment}\n")


fp.close()
resp.close()

print("爬取完成")
2.3.2 需求 爬取 电影天堂电影信息
import re
import requests

url = "https://www.dy2018.com/"
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36"
}

obj_1 = re.compile(r"2022必看热片.*?</ul>",re.S)
obj_2 = re.compile(r"<li><a href='(?P<add>.*?)' title=(?P<name>.*?)>",re.S)
obj_3 = re.compile(r'<td style="WORD-WRAP: break-word" bgcolor="#fdfddf"><a href="(?P<link_1>.*?)">',re.S)

resp = requests.get(url=url,headers=headers)
resp.encoding = "gb2312"
page_source = resp.text

# 抓取必看热片部分的页面代码
result_1 = re.findall(obj_1,page_source)

result_2 = re.finditer(obj_2,result_1[0])
for item in result_2:
    url_child =url+item.group("add")[1:]
    print(item.group("name")[1:-1])
    resp_2 = requests.get(url=url_child,headers=headers)
    resp_2.encoding = "gb2312"
    page_source_1 = resp_2.text

    result_3 = obj_3.finditer(page_source_1)
    for item_1 in result_3:
        print(item_1.group("link_1"))
    print("")

resp.close()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值