2015-10-15 17 views
2

我試圖解析來自一個網頁的數據。這個網頁允許你(根據robots.txt)每分鐘發送2000個請求。用Python解析更快

問題是我試過的一切都太慢了。這臺服務器的響應非常快。

from multiprocessing.pool import ThreadPool as Pool 

import datetime 
import lxml.html as lh 
from bs4 import BeautifulSoup 
import requests 

with open('products.txt') as f: 
    lines = f.readlines() 

def update(url): 

    html = requests.get(url).content # 3 seconds 

    doc = lh.parse(html) # almost 12 seconds (with commented line below) 

    soup = BeautifulSoup(html) # almost 12 seconds (with commented line above) 

pool = Pool(10) 

for line in lines[0:100]: 
    pool.apply_async(update, args=(line[:-1],)) 

pool.close() 

now = datetime.datetime.now() 
pool.join() 
print datetime.datetime.now() - now 

正如我評論到代碼 - 當我嘗試只是html = requests.get(url) 100個網址做,時間是偉大的 - 下3秒。

問題是,當我想使用一些解析器 - HTML預處理成本約10秒和更多,這是太多了。

你會推薦我什麼來縮短時間?

編輯:我試圖使用SoupStrainer - 它稍快,但沒有太明顯 - 9秒。

html = requests.get(url).content 

product = SoupStrainer('div',{'class': ['shopspr','bottom']}) 

soup = BeautifulSoup(html,'lxml', parse_only=product) 

回答

2

根據你需要從頁面中提取什麼,也許你不需要完整的DOM。也許你可以用HTMLParser(Python3中的html.parser)逃脫。它應該更快。

我會解耦讓頁面解析頁面,例如兩個池,一個是獲取頁面並填充一個隊列,另一個池從隊列中獲取頁面並解析它們。這將使用可用資源稍微好一點,但它不會是一個很大的加速。如果服務器開始以較大的延遲服務頁面,副作用可能會使工作人員忙於排隊。

+0

謝謝你的回答。由於我使用Python 2.7,是否有一些替代Python 3的HTMLParser?謝謝 –

+0

@Milan,'HTMLParser'是2.7,它在Python 3 – user1514631

+0

@Milan中重命名爲'html.parser',IO與Processing的分離可能是值得的,考慮到你已經不是一個很大的努力做多處理 – user1514631