1. 程式人生 > 其它 >Python爬蟲 教程: re正則表示式解析html頁面

Python爬蟲 教程: re正則表示式解析html頁面

技術標籤:python正則表示式

  • 正則表示式(Regular Expression)是一種文字模式,包括普通字元(例如,a 到 z 之間的字母)和特殊字元(稱為"元字元")。

  • 正則表示式通常被用來匹配、檢索、替換和分割那些符合某個模式(規則)的文字。

一、常用正則表示式

單字元:
        . : 除換行以外所有字元
        [][aoe] [a-w] 匹配集合中任意一個字元
        \d :數字  [0-9]
        \D : 非數字
        \w :數字、字母、下劃線、中文
        \W : 非\w
        \s :所有的空白字元包,
括空格、製表符、換頁符等等。等價於 [ \f\n\r\t\v]。 \S : 非空白 數量修飾: * : 任意多次 >=0 + : 至少1>=1 ? : 可有可無 0次或者1{m} :固定m次 hello{3,} {m,} :至少m次 {m,n} :m-n次 邊界: $ : 以某某結尾 ^ : 以某某開頭 分組: (ab) 貪婪模式: .* 非貪婪(惰性)模式: .
*? re.I : 忽略大小寫 re.M :多行匹配 re.S :單行匹配 re.sub(正則表示式, 替換內容, 字串)

練習:

import re

#提取出python
key="javapythonc++php"
re.findall('python',key)[0]            # 都有引號

#提取出hello world
key="<html><h1>hello world<h1></html>"
re.findall('<h1>(.*)<h1>'
,key)[0] #提取170 string = '我喜歡身高為170的女孩' re.findall('\d+',string) #提取出http://和https:// key='http://www.baidu.com and https://boob.com' re.findall('https?://',key) #提取出hello key='lalala<hTml>hello</HtMl>hahah' #輸出<hTml>hello</HtMl> re.findall('<[Hh][Tt][mM][lL]>(.*)</[Hh][Tt][mM][lL]>',key) #提取出hit. key='[email protected]' #想要匹配到hit. re.findall('h.*?\.',key) #匹配sas和saas key='saas and sas and saaas' re.findall('sa{1,2}s',key) #匹配出i開頭的行 string = '''fall in love with you i love you very much i love she i love her''' re.findall('^i.*',string,re.M) #匹配全部行 string1 = """<div>靜夜思 窗前明月光 疑是地上霜 舉頭望明月 低頭思故鄉 </div>""" re.findall('.*',string1,re.S)

注意:re.findall()通常匹配出來的是列表,所以要通過索引的方式將內容提取出來。

二、資料解析-正則表示式

1. 需求:爬取糗事百科中所有糗圖照片

'''
遇到問題沒人解答?小編建立了一個Python學習交流QQ群:778463939
尋找有志同道合的小夥伴,互幫互助,群裡還有不錯的視訊學習教程和PDF電子書!
'''
import requests
import re
import os

#建立一個資料夾
if not os.path.exists('./qiutuLibs'):        # 注意裡面要有引號
    os.mkdir('./qiutuLibs')
    
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
}

url = 'https://www.qiushibaike.com/pic/'
page_text = requests.get(url=url,headers=headers).text

#進行資料解析(圖片的地址)
ex = '<div class="thumb">.*?<img src="(.*?)" alt.*?</div>'        #不相關的可以用.*,非貪婪匹配

#re.S單行匹配
src_list = re.findall(ex,page_text,re.S)
print(src_list)

for src in src_list:
src = 'https:'+src                                #發現src屬性值不是一個完整的url,缺少了協議頭

    #對圖片的url單獨發起請求,獲取圖片資料.content返回的是二進位制型別的響應資料
    img_data = requests.get(url=src,headers=headers).content
    img_name = src.split('/')[-1]                            # url 最後一個斜槓的就是圖片名
    img_path = './qiutuLibs/'+img_name
    with open(img_path,'wb') as fp:
        fp.write(img_data)
        print(img_name,'下載成功!')

在這裡插入圖片描述
在這裡插入圖片描述
2. 糗圖分頁爬取

import requests
import re
import os

# 建立一個資料夾
if not os.path.exists('./qiutuLibs'):
    os.mkdir('./qiutuLibs')

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
}

#封裝一個通用的url模板
url = 'https://www.qiushibaike.com/pic/page/%d/?s=5185803'

for page in range(1,36):
    new_url = format(url%page)                            #不要忘了format,裡面不加引號
    page_text = requests.get(url=new_url, headers=headers).text

    # 進行資料解析(圖片的地址)
    ex = '<div class="thumb">.*?<img src="(.*?)" alt.*?</div>'
    src_list = re.findall(ex, page_text, re.S)                        # re.S單行匹配,因為頁面原始碼裡面有 \n

    # 發現src屬性值不是一個完整的url,缺少了協議頭
    for src in src_list:
        src = 'https:' + src
        # 對圖片的url單獨發起請求,獲取圖片資料.content返回的是二進位制型別的響應資料
        img_data = requests.get(url=src, headers=headers).content
        img_name = src.split('/')[-1]
        img_path = './qiutuLibs/' + img_name
        with open(img_path, 'wb') as fp:
            fp.write(img_data)
            print(img_name, '下載成功!')

在這裡插入圖片描述
觀察各個頁面之間的關聯
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述

輸入1,結果自動跳轉到首頁

在這裡插入圖片描述

注意:url使用format的編寫格式

#封裝一個通用的url模板
url = 'https://www.qiushibaike.com/pic/page/%d/?s=5185803'

for page in range(1,36):
    new_url = format(url%page)                            #不要忘了format,裡面不加引號

3. 爬取糗事百科指定頁面的糗圖,並將其儲存到指定資料夾中

'''
遇到問題沒人解答?小編建立了一個Python學習交流QQ群:778463939
尋找有志同道合的小夥伴,互幫互助,群裡還有不錯的視訊學習教程和PDF電子書!
'''
import requests
import re
import os

if __name__ == "__main__":
     url = 'https://www.qiushibaike.com/pic/%s/'
     headers={
         'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36',
     }

     #指定起始也結束頁碼
     page_start = int(input('enter start page:'))
     page_end = int(input('enter end page:'))

     #建立資料夾
     if not os.path.exists('images'):
         os.mkdir('images')

     #迴圈解析且下載指定頁碼中的圖片資料
     for page in range(page_start,page_end+1):
         print('正在下載第%d頁圖片'%page)
         new_url = format(url % page)
         response = requests.get(url=new_url,headers=headers)

         #解析response中的圖片連結
         e = '<div class="thumb">.*?<img src="(.*?)".*?>.*?</div>'
         pa = re.compile(e,re.S)
         image_urls = pa.findall(response.text)

          #迴圈下載該頁碼下所有的圖片資料
         for image_url in image_urls:
             image_url = 'https:' + image_url
             image_name = image_url.split('/')[-1]
             image_path = 'images/'+image_name

             image_data = requests.get(url=image_url,headers=headers).content
             with open(image_path,'wb') as fp:
                 fp.write(image_data)