2013-02-08 51 views
-6

我發現了一個名爲「Best Email Extractor」http://www.emailextractor.net/的程序。該網站稱它是用Python編寫的。我試圖寫一個類似的程序。上述程序每分鐘可提取約300 - 1000封電子郵件。我的程序每小時可提取約30-100封電子郵件。有人能給我提示如何提高我的程序的性能嗎?我寫道:Python中的電子郵件收割機:如何提高性能?

import sqlite3 as sql 
import urllib2 
import re 
import lxml.html as lxml 
import time 
import threading 


def getUrls(start): 

    urls = [] 
    try: 
     dom = lxml.parse(start).getroot() 
     dom.make_links_absolute() 

     for url in dom.iterlinks(): 
      if not '.jpg' in url[2]: 
       if not '.JPG' in url[2]: 
        if not '.ico' in url[2]: 
         if not '.png' in url[2]: 
          if not '.jpeg' in url[2]: 
           if not '.gif' in url[2]: 
            if not 'youtube.com' in url[2]: 
             urls.append(url[2]) 
    except: 
     pass 

    return urls 

def getURLContent(urlAdresse): 

    try: 
     url = urllib2.urlopen(urlAdresse) 
     text = url.read() 
     url.close() 
     return text 
    except: 
     return '<html></html>' 

def harvestEmail(url): 
    text = getURLContent(url) 

    emails = re.findall('[\w\-][\w\-\.][email protected][\w\-][\w\-\.]+[a-zA-Z]{1,4}', text) 

    if emails: 
     if saveEmail(emails[0]) == 1: 
      print emails[0] 

def saveUrl(url): 

    connection = sql.connect('url.db') 

    url = (url,) 

    with connection: 
     cursor = connection.cursor() 
     cursor.execute('SELECT COUNT(*) FROM urladressen WHERE adresse = ?', url) 
     data = cursor.fetchone() 
     if(data[0] == 0): 
      cursor.execute('INSERT INTO urladressen VALUES(NULL, ?)', url) 
      return 1 
     return 0 

def saveEmail(email): 
    connection = sql.connect('emails.db') 
    email = (email,) 

    with connection: 
     cursor = connection.cursor() 
     cursor.execute('SELECT COUNT(*) FROM addresse WHERE email = ?', email) 
     data = cursor.fetchone() 
     if(data[0] == 0): 
      cursor.execute('INSERT INTO addresse VALUES(NULL, ?)', email) 
      return 1 
    return 0 

def searchrun(urls): 
    for url in urls: 
     if saveUrl(url) == 1: 
      #time.sleep(0.6) 
      harvestEmail(url) 
      print url 
      urls.remove(url) 
      urls = urls + getUrls(url) 

urls1 = getUrls('http://www.google.de/#hl=de&tbo=d&output=search&sclient=psy-ab&q=DVD') 
urls2 = getUrls('http://www.google.de/#hl=de&tbo=d&output=search&sclient=psy-ab&q=Jolie') 
urls3 = getUrls('http://www.finanzen.net') 
urls4 = getUrls('http://www.google.de/#hl=de&tbo=d&output=search&sclient=psy-ab&q=Party') 
urls5 = getUrls('http://www.google.de/#hl=de&tbo=d&output=search&sclient=psy-ab&q=Games') 
urls6 = getUrls('http://www.spiegel.de') 
urls7 = getUrls('http://www.kicker.de/') 
urls8 = getUrls('http://www.chessbase.com') 
urls9 = getUrls('http://www.nba.com') 
urls10 = getUrls('http://www.nfl.com') 


try: 
    threads = [] 
    urls = (urls1, urls2, urls3, urls4, urls5, urls6, urls7, urls8, urls9, urls10) 

    for urlList in urls: 
     thread = threading.Thread(target=searchrun, args=(urlList,)).start() 
     threads.append(thread) 
    print threading.activeCount() 
    for thread in threads: 
     thread.join() 
except RuntimeError: 
    print RuntimeError 
+1

-1你會如何使用這些電子郵件給我的朋友?邀請人們參加你的派對? – Redian

+0

這不是關於電子郵件。我對如何更快地提取網站感興趣。 – Xirama

回答

3

我不認爲很多人會幫助你收穫的電子郵件。這是一個普遍厭惡的活動。

關於代碼中的性能瓶頸,您需要通過分析找出時間正在進行的地方。在最低級別,用一個不做任何處理但會返回有效輸出的啞元替換每個函數;所以電子郵件收集器可以返回100次相同地址的列表(或者這些URL結果中包含很多)。這將告訴你哪個功能花費你的時間。

的東西貼出來:

  1. 事先從服務器的URL後面的文件;如果您在每次運行腳本時向Google發送垃圾郵件,則可能會阻止您。從磁盤讀取比從互聯網上請求文件更快,並且可以單獨和同時完成。
  2. 數據庫代碼正在爲saveEmail等每個調用創建一個新的連接,這將花費大部分時間進行握手和身份驗證。最好有一個能夠保持連接在對話間保持連接的對象,或者更好地一次插入多條記錄。
  3. 一旦網絡和數據庫問題完成,正則表達式可能會圍繞它執行\b,以便匹配確實減少了回溯。
  4. 一系列如果不是'foo'in str:那麼如果不是'blah'in str ...就是糟糕的編碼。通過創建一個set甚至frozenset所有不允許的值(如ignoredExtensions = set([jpg,png,gif]))並與if not extension in ignoredExtensions之類的值進行比較,提取最後一個段並檢查多個值。還要注意的是,首先將擴展名轉換爲小寫字母將意味着更少的檢查和工作,不管它是JPG還是JPG。
  5. 最後,請考慮運行相同的腳本,而不要在多個命令行上進行線程化。除了協調不同的URL列表之外,沒有真正的需要在腳本內部進行線程化。坦率地說,只要在文件中有一組url列表就簡單多了,並且啓動一個單獨的腳本來處理每個腳本。讓操作系統執行多線程,它更好。
+0

...甚至大部分不會討厭電子郵件收集的人都會討厭你,因爲他們賺錢,而且不希望小公司競爭可能被浪費掉的小公司,垃圾郵件將以他們的名字發送出去...... – abarnert

+0

非常感謝您的回答。我現在使用多處理而不是線程。它提高了相當多的性能。我讀到應該避免使用Python的線程。我將嘗試Phil H在第5點中描述的技術。 – Xirama