效能比較:lxml庫,正則表示式,BeautifulSoup ,用資料證明lxml解析器速度快
阿新 • • 發佈:2018-12-18
Beautiful Soup支援的解析器
解析器 |
使用方法 |
優勢 |
劣勢 |
---|---|---|---|
Python標準庫 |
|
Python的內建標準庫、執行速度適中、文件容錯能力強 |
Python 2.7.3及Python 3.2.2之前的版本文件容錯能力差 |
lxml HTML解析器 |
|
速度快、文件容錯能力強 |
需要安裝C語言庫 |
lxml XML解析器 |
|
速度快、唯一支援XML的解析器 |
需要安裝C語言庫 |
html5lib |
|
最好的容錯性、以瀏覽器的方式解析文件、生成HTML5格式的文件 |
速度慢、不依賴外部擴充套件 |
通過以上對比可以看出,lxml解析器有解析HTML和XML的功能,而且速度快,容錯能力強,所以推薦使用它。
為何很多python爬蟲工程師都這樣說呢,下面我用例項來證明
例項:通過爬去糗事百科文字內容中的資訊來比較各解析器的效能,爬取的資訊有:使用者ID,發表的段子文字資訊,好笑數量和評論數量。如圖:
程式碼:
import re from bs4 import BeautifulSoup from lxml import etree import lxml import time import requests headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)' 'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36' } def get_lxml(url): datas = [] res = requests.get(url,headers = headers) html = etree.HTML(res.text) infos = html.xpath('//div[@id="content-left"]/div') for info in infos: ids = info.xpath('div[1]/a[2]/h2/text()') texts_x = info.xpath('a[1]/div[1]/span[1]/text()') num_laughs = info.xpath('div[2]/span[1]/i[1]/text()') num_comments = info.xpath('// */ i/text()') for id,text_x,num_luagh,num_comment in zip(ids,texts_x,num_laughs,num_comments): data = { 'id':id.strip(), 'text':text_x.strip(), 'num_luagh':num_luagh, 'num_comment':num_comment } datas.append(data) #print(datas) def get_re(url): datas=[] res = requests.get(url) ids = re.findall('<h2>(.*?)</h2>',res.text,re.S) texts_x = re.findall('<div class="content">.*?<span>(.*?)</span>',res.text,re.S) num_laughs = re.findall('<span class="stats-vote"><i class="number">(.*?)</i> 好笑</span>',res.text,re.S) num_comments = re.findall('<i class="number">(\d+)</i> 評論',res.text,re.S) for id,text_x,num_luagh,num_comment in zip(ids,texts_x,num_laughs,num_comments): data = { 'id':id.strip(), 'text':text_x.strip(), 'num_luagh':num_luagh.strip(), 'num_comment':num_comment.strip() } datas.append(data) #print(datas) def get_BeautifulSoup(url): datas = [] res = requests.get(url) soup = BeautifulSoup(res.text,'lxml') ids = soup.select('div.author.clearfix > a > h2') #print(ids) texts_x = soup.select('a.contentHerf > div > span') #print(texts_x) num_laughs = soup.select('div.stats > span.stats-vote > i') #print(num_laughs) num_comments = soup.select('i') #print(num_comments) for id,text_x,num_luagh,num_comment in zip(ids,texts_x,num_laughs,num_comments): data = { 'id':id.get_text().strip(), 'text':text_x.get_text().strip(), 'num_luagh':num_luagh.get_text().strip(), 'num_comment':num_comment.get_text().strip() } datas.append(data) #print(datas) if __name__=='__main__': urls = ['https://www.qiushibaike.com/text/page/{}/'.format(str(i)) for i in range(1,14)] for name,function in [('lxml',get_lxml),('re',get_re),('BeautifulSoup',get_BeautifulSoup)]: start = time.time() for url in urls: function(url) time.sleep(0.2) end = time.time() print(name,end-start)
執行結果:
資料證明,lxml效能遠遠大於正則表示式和BeautifulSoup。
謝謝您的閱讀!