Python用正则表达式实现爬取古诗文网站信息

作者:码农飞哥 时间:2021-08-30 07:12:51 

分析古诗文网站

下图1展示了古诗文网站—》诗文 栏目的首页数据。该栏目的地址是:https://so.gushiwen.cn/shiwens/

Python用正则表达式实现爬取古诗文网站信息

第二页的地址是:https://so.gushiwen.cn/shiwens/default.aspx?page=2&tstr=&astr=&cstr=&xstr= 。依次类推第n页的地址就是page=n。其他不变。

1. 用正则表达式获取总页数

Python用正则表达式实现爬取古诗文网站信息

匹配的正则表达式是r'<div class="pagesright">.*?<span .*?>(.*?)</span>'

  1. 首先,r修饰的字符串是原生字符串,首先匹配到<div class="pagesright"> 标签,然后再通过.*?匹配到里面的里面的<a>标签<span>标签等。这里. 可以匹配到任意的一个字符(换行符除外),* 号可以匹配0或者任意多个字符。? 号表示只能匹配到1个或者0个。这里加上?号是为了使用非贪婪模式。

  2. <span .*?> 通过匹配到存放总页数的<span>标签。在标签里指定.*?

  3. (.*?) 加上() 可以指定不同的分组,这里我们只需要获取页数所以就单独添加一个分组。

所以,最终的代码是:


def get_total_pages():
   resp = requests.get(first_url)
   # 获取总页数
   ret = re.findall(r'<div class="pagesright">.*?<span .*?>(.*?)</span>', resp.text, re.DOTALL)
   result = re.search('\d+', ret[0])
   for page_num in range(int(result.group())):
       url = 'https://so.gushiwen.cn/shiwens/default.aspx?page=' + str(page_num)
       parse_page(url)

在findall方法中传入re.DOTALL参数是为了是. 号可以匹配到换行符\n。

前面ret的结果是/ 5页。再获取5这个数字的话,还需要做一次匹配查找,这就是通过re.search('\d+', ret[0]) 来进行查找。

2. 提取诗的标题

Python用正则表达式实现爬取古诗文网站信息

如上图2展示了诗的标题的HTML源码,从中可以看出诗的标题被存在<b>标签 匹配诗的标题的正则表达式是<div class="cont">.*?<b>(.*?)</b>

首先还是匹配到<div class="cont"> 标签,接着就是匹配<b>(.*?)</b> 这里还是采用非贪婪模式来进行匹配。

3. 提取作者和朝代

Python用正则表达式实现爬取古诗文网站信息

如上图3展示了诗的作者和朝代的HTML源码,从中可以看出作者和朝代都是在<p class="source"></p> 标签下的两个a标签中。

3.1 提取作者

提取作者的正则表达式是<p class="source">.*?<a .*?>(.*?)</a> 首先还是匹配到<p class="source"> 标签。接着就是匹配第一个<a> 标签中的内容。

3.2 提取朝代

提取朝代的正则表达式是<p class="source">.*?<a .*?><a .*?>(.*?)</a> 与提取作者不同的是多了一个<a .*?> ,这是因为朝代在第二个<a>标签中。

4. 提取诗的内容

Python用正则表达式实现爬取古诗文网站信息

如上图4展示了诗的内容的HTML源码,从中可以看出诗句都在<div class="contson">标签中,所以只需要匹配到这个标签里的内容即可。其正则表达式是<div class="contson" .*?>(.*?)</div>。

但是这样匹配出来的数据是包含<br> 标签的。所以,我们需要通过sub 方法将这个标签替换掉。re.sub(r'<.*?>+', "", content)。

整理代码

至此,我们就将所有想要的数据都提取到了。接下来,我们还需要对数据进行处理。我们期望的最终数据格式是:


poems=[
       {
           "title": '渔家傲·花底忽闻敲两桨',
           "author":'张三',
           'dynasty':'唐朝',
           'content':'xxxxxx'
       }
         {
           "title": '鹅鹅鹅',
           "author":'李四',
           'dynasty':'唐朝',
           'content':'xxxxxx'
       }
   ]

前面,我们分别得到了所有标题的列表titles;所有作者的列表authors;所有朝代的列表dynastys;所有诗句的列表contents。

那么,我们如何将这些列表组合成上面的那种形式呢?

这里,就需要用到 zip 函数了。该函数可以将多个列表组合成一个新的列表,其中列表的元素是元组。比如:


a=['name','age']
b=['张三',18]
c=zip(a,b)

调用zip 方法之后得到一个zip对象,该对象可以转换成list 对象。最终得到的结果如下图5

Python用正则表达式实现爬取古诗文网站信息

完整源代码


# -*- utf-8 -*-
"""
@url: https://blog.csdn.net/u014534808
@Author: 码农飞哥
@File: gushiwen_rep.py
@Time: 2021/12/7 07:40
@Desc: 用正则表达式爬取古诗文网站
古诗文网站的地址:
https://www.gushiwen.cn/
"""
import re
import requests

headers = {
   'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36'
}

first_url = 'https://so.gushiwen.cn/shiwens/default.aspx'

def get_total_pages():
   resp = requests.get(first_url)
   # 获取总页数
   ret = re.findall(r'<div class="pagesright">.*?<span .*?>(.*?)</span>', resp.text, re.DOTALL)
   result = re.search('\d+', ret[0])
   for page_num in range(int(result.group())):
       url = 'https://so.gushiwen.cn/shiwens/default.aspx?page=' + str(page_num)
       parse_page(url)

# 解析页面
def parse_page(url):
   resp = requests.get(url)
   text = resp.text
   # 提取标题 (.*) 进行分组,只提取<b>标签中的内容,默认情况下 .不能匹配\n。加上re.DOTALL 表示.号可以匹配所有,贪婪模式
   # titles = re.findall(r'<div class="cont">.*<b>(.*)</b>', text,re.DOTALL)
   # 非贪婪模式
   titles = re.findall(r'<div class="cont">.*?<b>(.*?)</b>', text, re.DOTALL)
   # 提取作者
   authors = re.findall(r'<p class="source">.*?<a .*?>(.*?)</a>', text, re.DOTALL)
   # 提取朝代
   dynastys = re.findall(r'<p class="source">.*?<a .*?><a .*?>(.*?)</a>', text, re.DOTALL)
   # 提取诗句
   content_tags = re.findall(r'<div class="contson" .*?>(.*?)</div>', text, re.DOTALL)
   contents = []
   for content in content_tags:
       content = re.sub(r'<.*?>+', "", content)
       contents.append(content)
   poems = []

for value in zip(titles, authors, dynastys, contents):
       # 解包
       title, author, dynasty, content = value
       poems.append(
           {
               "title": title,
               "author": author,
               'dynasty': dynasty,
               'content': content
           }
       )
   print(poems)
   """
   poems=[
       {
           "title": '渔家傲·花底忽闻敲两桨',
           "author":'张三',
           'dynasty':'唐朝',
           'content':'xxxxxx'
       }
         {
           "title": '渔家傲·花底忽闻敲两桨',
           "author":'张三',
           'dynasty':'唐朝',
           'content':'xxxxxx'
       }
   ]
   """

"""
zip 函数
a=['name','age']
b=['张三',18]
c=zip(a,b)
c=[
   ('name','张三'),
   ('age',18)
]
"""

if __name__ == '__main__':
   get_total_pages()

最终的运行结果是:

Python用正则表达式实现爬取古诗文网站信息

来源:https://blog.csdn.net/u014534808/article/details/121764730

标签:Python,正则表达式,爬取,信息
0
投稿

猜你喜欢

  • Go语言基础switch条件语句基本用法及示例详解

    2024-04-26 17:33:30
  • Python PyQt5运行程序把输出信息展示到GUI图形界面上

    2021-02-08 22:41:59
  • 详细介绍mysql中limit与offset的用法

    2024-01-21 10:52:48
  • 深入理解 ES6中的 Reflect用法

    2024-04-16 09:30:44
  • div遮罩层实现实例代码

    2009-01-11 18:38:00
  • 解决python通过cx_Oracle模块连接Oracle乱码的问题

    2023-04-30 23:25:45
  • sql注入过程详解_动力节点Java学院整理

    2024-01-12 19:43:59
  • pytorch中F.avg_pool1d()和F.avg_pool2d()的使用操作

    2023-11-30 01:20:41
  • Python如何使用Gitlab API实现批量的合并分支

    2023-01-31 18:17:45
  • Django admin组件的使用

    2021-05-20 06:03:08
  • Python中time库的使用(日期时间)

    2022-11-12 09:04:23
  • Javascript验证方法大全

    2024-04-17 10:19:44
  • 页面重构中的模块化思维

    2009-06-28 15:36:00
  • 在mac下查找python包存放路径site-packages的实现方法

    2023-06-12 21:12:36
  • 微信小程序实现点击导航标签滚动定位到对应位置

    2024-05-10 13:59:17
  • Python判断和循环语句的分析与应用

    2021-09-28 02:46:59
  • 分享JavaScript与Java中MD5使用两个例子

    2024-05-22 10:40:17
  • 详解PyTorch中Tensor的高阶操作

    2021-11-24 12:08:00
  • 更改Python的pip install 默认安装依赖路径方法详解

    2023-01-05 20:55:28
  • GoLang nil与interface的空指针深入分析

    2024-02-18 01:58:50
  • asp之家 网络编程 m.aspxhome.com