1. 程式人生 > >Python3,通過re模組中的sub()和findall()2個方法提升爬蟲提取資料的效率

Python3,通過re模組中的sub()和findall()2個方法提升爬蟲提取資料的效率

直接上Demo:

測試資料 - HTML:

'''<div id=\"songs-list\">"
			"<h2 class=\"title\">各種汽車</h2>"
			"<p class=\"introduction\">"
				"各種汽車列表"
			"</p>"
			"<ul id=\"list\" class=\"list-group\">"
				"<li data-view=\"2\">奧迪TT</li>"
				"<li data-view=\"7\">"
					"<a href=\"/2.png\" type=\"大眾\">CC</a>"
				"</li>"
				"<li data-view=\"4\" class=\"active\">"
					"<a href=\"/3.png\" type=\"寶馬\">Mini</a>"
				"</li>"
				"<li data-view=\"6\"><a href=\"/4.png\" type=\"奧迪\">Q7</a></li>"
				"<li data-view=\"5\"><a href=\"/5.png\" type=\"吉利\">金剛</a></li>"
				"<li data-view=\"5\">"
					"<a href=\"/6.png\" type=\"大眾\"><i class=\"fa fa-user\"></i>速騰</a>"
				"</li>"
			"</ul>"
   "</div>'''

HTML結構分析,

思路1,若想要獲取每類汽車下面的具體汽車名字,python需要去解析HTML中的節點,有的汽車名,

1。裸露在'<li></li>'標籤下,

2。有的在'<li><a></a></li>'標籤下,

通過上面分析,我們構造的正則需要匹配上面2種情況,如下:

"<li.*?>\s*?(<a.*?>)?(\w+)(</a>)?\s*?</li>"
思路2,通過re模組的sub(),去除標籤'<a></a>',簡化HTML中的節點。構造2個匹配規則:

用於匹配HTML中所有標籤:'<a></a>' ,

"<a.*?>|</a>"
用於提取被簡化後HTML中的資料:
"<li.*?>(\w+)</li>"


測試Python程式碼:

import re
import time


def reTest1(str2):
    """
        比較re模組下findall()
        與findall()+sub()提取頁面資料效率和複雜程度
    
    """

    #匹配規則
    part = r"<li.*?>\s*?(<a.*?>)?(\w+)(</a>)?\s*?</li>"
    
    #實際操作頁面時,re.S,使萬用字元可以匹配換行符
    ret = re.findall(part, str2, re.S)

    for i in ret:
        print(i[1])

def reTest2(str2):
    """
        比較re模組下findall()
        與findall()+sub()提取頁面資料效率和複雜程度
    
    """

    #匹配規則
    part = r"<li.*?>\s*?(<a.*?>)?(\w+)(</a>)?\s*?</li>"
    
    #想法:通過re模組sub()方法去掉標籤:<a></a>
    #sub(RegExp, NewString, oldString, args)
    #RegExp: 匹配規則
    #NewString: 想要要替換的字串
    #oldString: 原始字串
    #args: re.S ...
    subStr = re.sub("<a.*?>|</a>", "", str2, re.S)

    #實際操作頁面時,re.S,使萬用字元可以匹配換行符
    ret = re.findall("<li.*?>(\w+)</li>", subStr, re.S)
    
    for i in ret:
        print(i)

if __name__ == "__main__":

    str2 = ("'''<div id=\"Car-list\">"
			"<h2 class=\"title\">各種汽車</h2>"
			"<p class=\"introduction\">"
				"各種汽車列表"
                                	"</p>"
			"<ul id=\"list\" class=\"list-group\">"
				"<li data-view=\"2\">奧迪TT</li>"
				"<li data-view=\"7\">"
					"<a href=\"/2.png\" type=\"大眾\">CC</a>"
				"</li>"
				"<li data-view=\"4\" class=\"active\">"
					"<a href=\"/3.png\" type=\"寶馬\">Mini</a>"
				"</li>"
				"<li data-view=\"6\"><a href=\"/4.png\" type=\"奧迪\">Q7</a></li>"
				"<li data-view=\"5\"><a href=\"/5.png\" type=\"吉利\">金剛</a></li>"
				"<li data-view=\"5\">"
					"<a href=\"/6.png\" type=\"大眾\"><i class=\"fa fa-user\"></i>速騰</a>"
				"</li>"
			"</ul>"
			"</div>'''")
    
    #測試1:find()
    start1 = time.time()
    reTest1(str2)
    end1 = time.time()
   
    print("*"*50)

    #測試2,find()+sub()
    start2 = time.time()
    reTest2(str2)
    end2 = time.time()
    
    print("*"*50)
    print("通過find()直接提取目標資料,所用時間Time1:")
    print(end1 - start1)
    print("")
    print("通過sub() + find()提取目標資料,所用時間Time2:")
    print(end2 - start2)
    print("")
    print("時間差:")
    print("Time1 - Time2=", (end1-start1)-(end2-start2))

測試結果:



總結:
測試結果中,很明顯,思路2比思路1提取資料效率明顯高,re模組中各種方法組合一起有奇效
大量資料中,在保證精準的前提下,提升數去獲取的效率也是很重要的