2015-12-16 50 views
0

我有一個python 3腳本,它使用庫urllib.request和BeautifulSoup加載網站的內容,並將信息從它導出到csv文件或MySQL數據庫。 下面是代碼主線從腳本:從萬維網頁導出信息

# ... 

url = urllib.request.urlopen("<urls here>") 
html = url.read() 
url.close() 
soup = BeautifulSoup(html, "html.parser") 
# Create lists for html elements 
nadpis = soup.find_all("span", class_="nadpis")  
# Some more soups here... 

onpage = len(no) # No. of elements on page 
for i in range(onpage): 
    nadpis[i] = one_column(nadpis[i].string) 
    # Some more soups here 

if csv_export: 
    with open("export/" + category[c][0] + ".csv", "ab") as csv_file: 
     wr = csv.writer(csv_file, delimiter=';', quotechar='|', quoting=csv.QUOTE_MINIMAL, lineterminator='\n') 
     wr.writerow("<informations from soup>") 

# Insert to database 
if db_insert: 
    try:   
     cursor.execute("<informations from soup>") 
     conn.commit() 
    except Exception: 
     print("Some MySQL error...") 
     break 

# ... 

全部腳本有200行代碼,所以我不會在這裏的垃圾郵件了。一切正常。問題是我需要掃描並從大量網頁中導出信息(一切都在while循環中,但現在不需要),並且它變得非常慢(幾個小時的運行時間)。

有沒有更快的方法來做到這一點?

我實現了多處理,所以我可以利用每個CPU核心,但無論如何,它可能需要24小時才能導出所有內容。我甚至在亞馬遜EC2服務器上做了一個測試,但無論如何它不是更快,所以問題不在於我的PC或互聯網連接速度很慢。

+0

有很多方法可以提高性能,但沒有在你的問題的足夠信息。您應該確定可能的瓶頸(遠程服務器,帶寬,延遲,CPU,磁盤等),並查看是否可以儘快實現您的性能目標 – jfs

回答

1

如果您遇到性能問題,我會建議您開始profiling您的代碼。這會給你一個關於你的代碼大部分時間在哪裏運行的非常詳細的想法。您還可以測量腳本每個網頁的時間,也許您會發現某些網頁的加載時間比其他網頁的時間多,這表明您不受帶寬的限制,而是受到服務器的限制正試圖訪問。

但是,你稱之爲'噸的網頁'?如果您的腳本進行了合理的優化,並且如果您使用的是所有CPU內核,那麼看起來您可能只需要很多網頁即可取消,以便儘快完成它(順便說一下,您希望它的速度有多快? )

+0

。我讀到了這個名爲ZMap的工具:http://pastebin.com/Ah2v2fiW一些像它一樣完美的東西,所以我想知道現在是不是有一些庫。 「噸網頁」我的意思是像個人網頁200k。我會研究分析,感謝提示。 –

+0

ZMap看起來像是一個掃描地址的工具,但似乎不適合報廢(但我可能是錯的)。 另外,我會建議你從寫入過程(在一個CVS或一個數據庫)中分離出scraping過程。由於您使用的是並行化,因此您可以使用一名專業工作人員輸出結果,這樣可以騰出一段時間讓其他工作人員取消您的內容。 – Nitlev

0

我會建議simple-requests,是這樣的:

from simple_requests import Requests 

# Creates a session and thread pool 
requests = Requests(concurrent=2, minSecondsBetweenRequests=0.15) 

# Cookies are maintained in this instance of Requests, so subsequent requests 
# will still be logged-in. 
urls = [ 
    'http://www.url1.com/', 
    'http://www.url2.com/', 
    'http://www.url3.com/' ] 

# Asynchronously send all the requests for profile pages 
for url_response in requests.swarm(urls): 
    html = url_response.html 
    soup = BeautifulSoup(html, "html.parser") 

    # Some more soups here... 

    # Write out your file...