Python3,通過re模組中的sub()和findall()2個方法提升爬蟲提取資料的效率
阿新 • • 發佈:2019-02-01
直接上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模組中各種方法組合一起有奇效
大量資料中,在保證精準的前提下,提升數去獲取的效率也是很重要的