目录

如何用正则表达式爬取古诗文网中的数据python爬虫

如何用正则表达式爬取古诗文网中的数据(python爬虫)

一、了解正则表达式的基本内容:

https://i-blog.csdnimg.cn/direct/fb4a217e40a04ad8add1a6eeb2f96715.png

什么是正则表达式

正则表达式(Regular Expression,简称 regex)是一种用于 匹配字符串 的模式。它通过特定的语法规则,可以高效地搜索、替换和提取文本中的特定内容。正则表达式广泛应用于文本处理、数据验证、日志分析等领域。

正则表达式在爬虫中的应用

在爬虫中,正则表达式主要用于从 网页源码中提取所需信息 。以下是其主要应用场景:

  1. 数据提取

    • 从HTML中提取特定标签的内容,如链接、标题、图片地址等。
    • 示例:提取所有链接: <a\s+(?:[^>]*?\s+)?href="([^"]*)"
  2. 数据清洗

    • 去除多余的空格、换行符或HTML标签。
    • 示例:去除HTML标签: <[^>]+>
  3. 数据验证

    • 验证提取的数据是否符合预期格式,如邮箱、日期等。
    • 示例:验证邮箱: ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+[a-zA-Z]{2,}$
  4. URL匹配

    • 匹配特定模式的URL,用于过滤或分类。
    • 示例:匹配图片URL: https?://[^\s]+?(jpg|png|gif)

正则表达式的核心知识点

  1. 基本语法

    • 字符匹配 :普通字符匹配自身,如 a 匹配字符 “a”。
    • 元字符 :具有特殊含义的字符,如 . 匹配任意字符, * 匹配前一个字符的零次或多次。
  2. 字符类

    • [abc] 匹配 “a”、“b” 或 “c”。
    • [^abc] 匹配除 “a”、“b”、“c” 之外的字符。
    • \d 匹配数字, \w 匹配字母、数字或下划线, \s 匹配空白字符。
  3. 量词

    • * :零次或多次。
    • + :一次或多次。
    • ? :零次或一次。
    • {n} :恰好 n 次。
    • {n,} :至少 n 次。
    • {n,m} :n 到 m 次。
  4. 分组和捕获

    • (abc) 匹配 “abc” 并捕获。
    • (?:abc) 匹配 “abc” 但不捕获。
  5. 锚点

    • ^ 匹配字符串开头。
    • $ 匹配字符串结尾。
    • \b 匹配单词边界。
  6. 贪婪与懒惰匹配

    • 默认是贪婪匹配,尽可能匹配更多字符。
    • 在量词后加 ? 可进行懒惰匹配,尽可能匹配更少字符。
    • 示例: a.*?b 匹配 “a” 和 “b” 之间的最短内容。

总结

正则表达式是爬虫中强大的工具,能够高效提取和清洗数据。掌握其基本语法和常用技巧,能显著提升爬虫的开发效率和数据处理能力。

https://i-blog.csdnimg.cn/direct/a4117681600c457f933d5984f6a36ad6.png

https://i-blog.csdnimg.cn/direct/1ec7972f2dc045fdbc9446838b5fb4ed.png

https://i-blog.csdnimg.cn/direct/bd650a2facd14861978896fb51a83de1.png

https://i-blog.csdnimg.cn/direct/385dada51907400a800a9fe6bfaed3e5.png

https://i-blog.csdnimg.cn/direct/4982b3c402be4f21a5215c925b86b751.png

同时代码中还涉及到了re库的使用:

re 是 Python 标准库中用于处理正则表达式的模块,提供了丰富的函数和方法来操作字符串。通过 re 库,你可以轻松实现字符串的匹配、查找、替换和分割等操作。

re 库是 Python 中处理正则表达式的强大工具,提供了多种函数和方法来操作字符串。掌握 re 库的使用,可以显著提升文本处理的效率和灵活性,尤其在爬虫开发中, re 库是不可或缺的工具。

re 库的核心功能

  1. 编译正则表达式
    • re.compile(pattern, flags=0) :将正则表达式编译成一个正则对象,便于重复使用。

    • 示例:

      pattern = re.compile(r'\d+')
  2. 匹配字符串
    • re.match(pattern, string, flags=0) :从字符串开头匹配正则表达式,返回匹配对象或 None

    • 示例:

      match = re.match(r'\d+', '123abc')
      if match:
          print(match.group())  # 输出: 123
  3. 搜索字符串
    • re.search(pattern, string, flags=0) :在字符串中搜索第一个匹配项,返回匹配对象或 None

    • 示例:

      search = re.search(r'\d+', 'abc123def')
      if search:
          print(search.group())  # 输出: 123
  4. 查找所有匹配项
    • re.findall(pattern, string, flags=0) :返回所有匹配项的列表。

    • 示例:

      findall = re.findall(r'\d+', 'a1b2c3')
      print(findall)  # 输出: ['1', '2', '3']
  5. 查找所有匹配项(返回迭代器)
    • re.finditer(pattern, string, flags=0) :返回所有匹配项的迭代器,每个元素是一个匹配对象。

    • 示例:

      finditer = re.finditer(r'\d+', 'a1b2c3')
      for match in finditer:
          print(match.group())  # 输出: 1, 2, 3
  6. 替换字符串
    • re.sub(pattern, repl, string, count=0, flags=0) :替换字符串中所有匹配项,返回替换后的字符串。

    • 示例:

      sub = re.sub(r'\d+', 'X', 'a1b2c3')
      print(sub)  # 输出: aXbXcX
  7. 分割字符串
    • re.split(pattern, string, maxsplit=0, flags=0) :根据正则表达式分割字符串,返回列表。

    • 示例:

      split = re.split(r'\d+', 'a1b2c3')
      print(split)  # 输出: ['a', 'b', 'c', '']

re 库的常用方法详解

  1. 匹配对象的方法

    • group() :返回匹配的字符串。
    • start() :返回匹配的起始位置。
    • end() :返回匹配的结束位置。
    • span() :返回匹配的 (起始, 结束) 位置元组。
  2. 编译标志

    • re.IGNORECASEre.I :忽略大小写。
    • re.MULTILINEre.M :多行模式, ^$ 匹配每行的开头和结尾。
    • re.DOTALLre.S. 匹配包括换行符在内的所有字符。
    • re.VERBOSEre.X :允许在正则表达式中添加注释和空白符。

二、具体的爬虫代码解释(以古诗文网为例)

url= [唐代诗文_古诗文网

https://csdnimg.cn/release/blog_editor_html/release2.3.8/ckeditor/plugins/CsdnLink/icons/icon-default.png?t=P1C7 “唐代诗文_古诗文网”) (以唐代的诗文题目为例,可扩充)

https://i-blog.csdnimg.cn/direct/574a2a7306404ba6a43f84d09f8f3b8d.png

右键检查 :

https://i-blog.csdnimg.cn/direct/14e2803a913143f78379c9d84f6eacd9.png

具体的代码解释 :

1. requests 库的使用

  • 功能requests 是一个用于发送 HTTP 请求的 Python 库,常用于爬虫中获取网页内容。

  • 知识点

    • requests.get(url, headers=headers) :发送 GET 请求,获取网页内容。

    • resp.encoding = 'utf-8' :设置响应的编码格式,确保正确解析中文内容。

    • resp.text :获取响应的文本内容(HTML 源码)。

    • headers :请求头,用于模拟浏览器访问,避免被网站反爬虫机制拦截。

      • User-Agent :标识客户端类型(如浏览器),示例中使用的是 Chrome 浏览器的标识。

2. 正则表达式( re 库)

  • 功能 :用于从 HTML 文本中提取目标数据(如古诗标题)。

  • 知识点

    • re.findall(pattern, string, flags) :从字符串中查找所有匹配正则表达式的部分,返回一个列表。

    • 正则表达式模式:

      • r'<div\sclass="cont">.*?<b>(.*?)</b>'

        • <div\sclass="cont"> :匹配 <div class="cont"> 标签。
        • .*? :非贪婪匹配任意字符(尽可能少匹配)。
        • <b>(.*?)</b> :匹配 <b> 标签中的内容, (.*?) 是捕获组,提取标题内容。
    • re.DOTALL 标志:使 . 匹配包括换行符在内的所有字符。


3. Python 函数

  • 功能 :将代码模块化,提高可读性和复用性。

  • 知识点

    • def parse_page(url) :定义一个函数,用于解析网页内容。
    • def spider() :定义一个函数,作为爬虫的入口。
    • if __name__ == '__main__': :确保脚本在直接运行时执行 spider() 函数,而在被导入时不执行。

4. URL 和请求头

  • 知识点

    • URL

      • https://www.gushiwen.cn/shiwens/default.aspx?cstr=%e5%94%90%e4%bb%a3 :目标网页地址。
      • cstr=%e5%94%90%e4%bb%a3 :URL 编码,表示查询参数(这里是“唐代”)。
    • 请求头

      • headers :用于模拟浏览器访问,避免被反爬虫机制拦截。
      • User-Agent :标识客户端类型,示例中使用的是 Chrome 浏览器的标识。

5. 编码问题

  • 知识点

    • resp.encoding = 'utf-8' :设置响应的编码格式为 UTF-8,确保正确解析中文内容。
    • 如果未设置编码,可能会导致乱码问题。

6. 代码执行流程

  • 知识点

    1. 调用 spider() 函数。
    2. spider() 函数调用 parse_page(url) ,传入目标 URL。
    3. parse_page(url) 发送 HTTP 请求,获取网页内容。
    4. 使用正则表达式从 HTML 中提取古诗标题。
    5. 打印提取的标题列表。
具体代码展示:
import requests
import re

url = "https://www.gushiwen.cn/shiwens/default.aspx?cstr=%e5%94%90%e4%bb%a3"
header = {
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 Edg/134.0.0.0"
}

def parse_page(url):
    resp = requests.get(url, headers=header)
    resp.encoding = 'utf-8'  # 确保编码正确
    html = resp.text
    # 调整正则表达式以匹配实际的HTML结构
    titles = re.findall(r'<div\sclass="cont">.*?<b>(.*?)</b>', html, re.DOTALL)
    print(titles)

def spider():
    url = "https://www.gushiwen.cn/shiwens/default.aspx?cstr=%e5%94%90%e4%bb%a3"  # 古诗文网
    parse_page(url)

if __name__ == '__main__':
    spider()
运行结果:

https://i-blog.csdnimg.cn/direct/0df89bfc1f9343acb38eba72fb5cda4f.png

三、改进建议:根据以上代码格式不光可以爬取古诗文题目也可以爬取内容作者等

https://i-blog.csdnimg.cn/direct/2004a63beefa42ceaaa887c94a951a2d.png

https://i-blog.csdnimg.cn/direct/8fd794164a4244f8a9f87dc2863d9355.png

所以后面的代码有改动:

import requests
import re

# 目标URL
url = "https://www.gushiwen.cn/shiwens/default.aspx?cstr=%e5%94%90%e4%bb%a3"

# 请求头,模拟浏览器访问
header = {
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 Edg/134.0.0.0"
}

def parse_page(url):
    # 发送HTTP请求,获取网页内容
    resp = requests.get(url, headers=header)
    resp.encoding = 'utf-8'  # 设置编码
    html = resp.text

    # 正则表达式提取古诗的标题、作者和内容
    poem_pattern = re.compile(
        r'<div class="cont">.*?<b>(.*?)</b>.*?'  # 标题
        r'<p class="source">.*?<a.*?>(.*?)</a>.*?<a.*?>(.*?)</a>.*?'  # 作者
        r'<div class="contson".*?>(.*?)</div>',  # 内容
        re.DOTALL
    )

    # 查找所有匹配的古诗
    poems = poem_pattern.findall(html)

    # 遍历提取结果
    for poem in poems:
        title = poem[0].strip()  # 标题
        author = f"{poem[1].strip()} {poem[2].strip()}"  # 作者
        content = re.sub(r'<.*?>', '', poem[3]).strip()  # 去除内容中的HTML标签

        # 打印结果
        print(f"标题: {title}")
        print(f"作者: {author}")
        print(f"内容: {content}")
        print("-" * 50)  # 分隔线

def spider():
    # 目标URL
    url = "https://www.gushiwen.cn/shiwens/default.aspx?cstr=%e5%94%90%e4%bb%a3"
    parse_page(url)

if __name__ == '__main__':
    spider()

https://i-blog.csdnimg.cn/direct/65e43462f59543d8aba55e1c6dbaa0a9.png

部分正则表达式的来源:

poem_pattern = re.compile(
    r'<div class="cont">.*?<b>(.*?)</b>.*?'  # 标题
    r'<p class="source">.*?<a.*?>(.*?)</a>.*?<a.*?>(.*?)</a>.*?'  # 作者
    r'<div class="contson">.*?>(.*?)</div>',  # 内容
    re.DOTALL
)

https://i-blog.csdnimg.cn/direct/c780411c2b6c46d2b1c9b9bdcbf6bc6d.png

https://i-blog.csdnimg.cn/direct/7140288e722348be8c1a73e3dfe555ee.png

https://i-blog.csdnimg.cn/direct/ad20b9fb0698492bbcb43916662987a1.png

https://i-blog.csdnimg.cn/direct/6ba7701398f949edbdf73dc83f379456.png

运行结果:

https://i-blog.csdnimg.cn/direct/c2e9541b0da04b019d48c6e6462ffc07.png