溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python怎么用正則表達式實現(xiàn)爬取古詩文網(wǎng)站信息

發(fā)布時間:2021-12-16 08:26:36 來源:億速云 閱讀:232 作者:iii 欄目:開發(fā)技術

本篇內容介紹了“Python怎么用正則表達式實現(xiàn)爬取古詩文網(wǎng)站信息”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

    分析古詩文網(wǎng)站

    下圖1展示了古詩文網(wǎng)站—》詩文 欄目的首頁數(shù)據(jù)。

    Python怎么用正則表達式實現(xiàn)爬取古詩文網(wǎng)站信息

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

    1. 用正則表達式獲取總頁數(shù)

    Python怎么用正則表達式實現(xiàn)爬取古詩文網(wǎng)站信息

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

    1. 首先,r修飾的字符串是原生字符串,首先匹配到<div class="pagesright"> 標簽,然后再通過.*?匹配到里面的里面的<a>標簽<span>標簽等。這里. 可以匹配到任意的一個字符(換行符除外),* 號可以匹配0或者任意多個字符。? 號表示只能匹配到1個或者0個。這里加上?號是為了使用非貪婪模式。

    2. <span .*?> 通過匹配到存放總頁數(shù)的<span>標簽。在標簽里指定.*?

    3. (.*?) 加上() 可以指定不同的分組,這里我們只需要獲取頁數(shù)所以就單獨添加一個分組。

    所以,最終的代碼是:

     def get_total_pages():
        resp = requests.get(first_url)
        # 獲取總頁數(shù)
        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參數(shù)是為了是. 號可以匹配到換行符\n。

    前面ret的結果是/ 5頁。再獲取5這個數(shù)字的話,還需要做一次匹配查找,這就是通過re.search('\d+', ret[0]) 來進行查找。

    2. 提取詩的標題

    Python怎么用正則表達式實現(xiàn)爬取古詩文網(wǎng)站信息

    如上圖2展示了詩的標題的HTML源碼,從中可以看出詩的標題被存在<b>標簽 匹配詩的標題的正則表達式是<div class="cont">.*?<b>(.*?)</b>

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

    3. 提取作者和朝代

    Python怎么用正則表達式實現(xiàn)爬取古詩文網(wǎng)站信息

    如上圖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怎么用正則表達式實現(xiàn)爬取古詩文網(wǎng)站信息

    如上圖4展示了詩的內容的HTML源碼,從中可以看出詩句都在<div class="contson">標簽中,所以只需要匹配到這個標簽里的內容即可。其正則表達式是<div class="contson" .*?>(.*?)</div>。

    但是這樣匹配出來的數(shù)據(jù)是包含<br> 標簽的。所以,我們需要通過sub 方法將這個標簽替換掉。re.sub(r'<.*?>+', "", content)。

    整理代碼

    至此,我們就將所有想要的數(shù)據(jù)都提取到了。接下來,我們還需要對數(shù)據(jù)進行處理。我們期望的最終數(shù)據(jù)格式是:

     poems=[
            {
                "title": '漁家傲·花底忽聞敲兩槳',
                "author":'張三',
                'dynasty':'唐朝',
                'content':'xxxxxx'
            }
              {
                "title": '鵝鵝鵝',
                "author":'李四',
                'dynasty':'唐朝',
                'content':'xxxxxx'
            }
        ]

    前面,我們分別得到了所有標題的列表titles;所有作者的列表authors;所有朝代的列表dynastys;所有詩句的列表contents。

    那么,我們如何將這些列表組合成上面的那種形式呢?

    這里,就需要用到 zip 函數(shù)了。該函數(shù)可以將多個列表組合成一個新的列表,其中列表的元素是元組。比如:

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

    調用zip 方法之后得到一個zip對象,該對象可以轉換成list 對象。最終得到的結果如下圖5

    Python怎么用正則表達式實現(xiàn)爬取古詩文網(wǎng)站信息

    完整源代碼

    # -*- utf-8 -*-
    """
    @url: https://blog.csdn.net/u014534808
    @Author: 碼農飛哥
    @File: gushiwen_rep.py
    @Time: 2021/12/7 07:40
    @Desc: 用正則表達式爬取古詩文網(wǎng)站
    古詩文網(wǎng)站的地址:
    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)
        # 獲取總頁數(shù)
        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 函數(shù)
    a=['name','age']
    b=['張三',18]
    c=zip(a,b)
    c=[
        ('name','張三'),
        ('age',18)
    ]
    """
    
    if __name__ == '__main__':
        get_total_pages()

    最終的運行結果是:

    Python怎么用正則表達式實現(xiàn)爬取古詩文網(wǎng)站信息

    “Python怎么用正則表達式實現(xiàn)爬取古詩文網(wǎng)站信息”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關的知識可以關注億速云網(wǎng)站,小編將為大家輸出更多高質量的實用文章!

    向AI問一下細節(jié)

    免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。

    AI