1. 程式人生 > 程式設計 >Python用正則表示式實現爬取古詩文網站資訊

Python用正則表示式實現爬取古詩文網站資訊

目錄
  • 分析古詩文
    • 1. 用正則表示式獲取總頁數
    • 2. 提取詩的標題
    • 3. 提取作者和朝代
    • 4. 提取詩的內容
  • 整理程式碼
    • 完整原始碼
      • 總結

        分析古詩文網站

        下圖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原始碼,從中可以看出詩的標題被存在標籤 匹配詩的標題的正則表示式是<div class="cont">.*?(.*?)

        首先還是匹配到<div class="cont"> 標籤,接著就是匹配(.*?) 這裡還是採用非貪婪模式來進行匹配。

        3. 提取作者和朝代

        Python用正則表示式實現爬取古詩文網站資訊

        如上圖3展示了詩的作者和朝代的HTML原始碼,從中可以看出作者和朝代都是在<p class="source"></p> 標籤下的兩個a標籤中。

        3.1 提取作者

        提取作者的正則表示式是<p class="sohttp://www.cppcns.comurce">.*?<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":'李四','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>',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
            # 提取標題 (.*) 進行分組,只提取標籤中的內容,預設情況下 .不能匹配\n。加上re.DOTALL 表示.號可以匹配所有,貪婪模式
            # titles = re.findall(r'<div class="cont">.*(.*)',text,re.DOTALL)
            # 非貪婪模式
            titles = re.findall(r'<div class="cont">.*?(.*?)',re.DOTALL)
            # 提取作者
            authors = re.findall(r'<p class="source">.*?<a .*?>(.*?)</a>',re.DOTALL)
            # 提取朝代
            dynastys = re.findall(r'<p class="source">.*?<a .*?><a .*?>(.*?)</a>',re.DOTALL)
            # 提取詩句
            content_tags = re.findall(r'<div class="contson" .*?>(.*?)</div>',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": '漁家傲花底忽聞敲兩槳','content':'xxxxxx'
                }
                  {
                    "title": '漁家傲花底忽聞敲兩槳','content':'xxxxxx'
                }
            ]
            """
        
        
        """
        zip 函式
        a=['name',b)
        c=[
            ('name','張三'),('age',18)
        ]
        """
        
        if __name__ == '__main__':
            get_total_pages()

        最終的執行結果是:

        Python用正則表示式實現爬取古詩文網站資訊

        總結

        本文以古詩文網為例演示瞭如何通過正則表示式來爬取網站資料。

        以上就是用正則表示式實現爬取古詩文網站資訊的詳細內容,更多關於Python正則表示式爬取網站資訊的資料請關注我們其它相關文章!