python 正则抓取古诗词
tags: #正则表达式 #HTML提取
- 匹配任意字符不能跨行:
.*
- 匹配任意字符包括换行符等:
[\s\S]*
- 捕获某前缀与某后缀之间的任意字符:
(.*?)
- 使用情况举例,捕获下面HTML中的文字“不迟any” HTML:
<a href='http://www.cnblogs.com/buchiany/'>不迟any</a>
匹配的正则表达式:<a.*?>(.*?)<\/a>
- 匹配任意空白(包含空格、\f换页符、\n换行符、\r回车符、\t制表符、\v垂直制表符):
[\s]*
使用情况举例,匹配下面HTML内容里第一行<tr>
和第三行<th>
,之间跨越了空白
HTML:
要匹配的内容第一部分<tr> <th>要匹配的内容第二部分
匹配的正则表达式:<tr>[\s]*<th>
group 详解
import re a = "123abc456" print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(0) #123abc456,返回整体 print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(1) #123 print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(2) #abc print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(3) #456
究其因
1. 正则表达式中的三组括号把匹配结果分成三组
- group() 同group(0)就是匹配正则表达式整体结果
- group(1) 列出第一个括号匹配部分,group(2) 列出第二个括号匹配部分,group(3) 列出第三个括号匹配部分。
2. 没有匹配成功的,re.search()返回None
3. 当然郑则表达式中没有括号,group(1)肯定不对了。
抓取古诗案例
# -*- coding:utf-8 -*-
import re
import requests
def crawl(start_url):
base_url = 'http://so.gushiwen.org'
req_headers = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'}
for i in range(1, 126):
restart_url = start_url + str(i) + '.aspx'
print(restart_url)
res = requests.get(restart_url, headers=req_headers)
if res.status_code == requests.codes.ok:
html = res.text
# 获取所有诗的链接
parttern_href = re.compile(r'<div class="cont">.*?<p><a .*? href="(.*?)" .*?>.*?</p>', flags=re.DOTALL) # 标红的部分为捕获 将会直接返回
hrefs = re.findall(parttern_href, html) # 在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。
# 获取每一首诗的内容,并保存到本地
with open('李白诗集.txt', mode='a', encoding='utf-8') as f:
for href in hrefs:
res = requests.get(base_url + href, headers=req_headers)
if res.status_code == requests.codes.ok:
# 标题
parttern_title = re.compile(r'<div class="cont">.*?<h1 .*?>(.*?)</h1>', re.DOTALL) # 标红的部分为捕获 将会直接返回
title = re.search(parttern_title, res.text).group(1)
# 内容
parttern_content = re.compile(r'<div class="cont">.*?<div class="contson" id=".*?">(.*?)</div>',re.DOTALL) # 标红的部分为捕获 将会直接返回
content = re.search(parttern_content, html).group(1) # 扫描整个字符串并返回第一个成功的匹配。
content = re.sub(r'<br />', '\n', content) # 用于替换字符串中的匹配项
content = re.sub(r'<p>', '', content)
content = re.sub(r'</p>', '', content)
print('正在获取 {title}'.format(title=title))
f.write('{title}{content}\n'.format(title=title, content=content))
if __name__ == '__main__':
start_url = 'https://so.gushiwen.org/authors/authorvsw_b90660e3e492A'
crawl(start_url)
import pyautogui import pyperclip
pyperclip.copy(songs) # 需要发送的内容早起的鸟儿有霾吸 pyautogui.hotkey('ctrl', 'v') # 按下 ctrl + v 粘贴内容 pyautogui.hotkey('Enter')
故乡明
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话