-6

"Best Email Extractor" http://www.emailextractor.net/というプログラムを見つけました。ウェブサイトによると、Pythonで書かれています。似たようなプログラムを書いてみました。上記のプログラムは、1 分あたり約 300 ~ 1000 通の電子メールを抽出します。私のプログラムは、1 時間あたり約 30 ~ 100 通の電子メールを抽出します。プログラムのパフォーマンスを改善する方法について誰かヒントを教えてもらえますか? 私は次のように書いた:

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\-\.]+@[\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
4

1 に答える 1

3

メールの収集を手伝ってくれる人はあまりいないと思います。一般的に嫌われている行為です。

コードのパフォーマンスのボトルネックについては、プロファイリングによって時間がどこにかかっているかを調べる必要があります。最低レベルでは、各関数を、処理は行わないが有効な出力を返すダミーに置き換えます。そのため、電子メール コレクタは同じアドレスのリストを 100 回返すことができます (または、これらの URL の結果に何回でも返されます)。これにより、どの機能に時間がかかっているかがわかります。

突出しているもの:

  1. 事前にサーバーから URL の背後にあるファイルを取得します。スクリプトを実行するたびに Google にスパムを送信すると、ブロックされる可能性があります。ディスクからの読み取りは、インターネットからファイルを要求するよりも高速であり、個別に同時に実行できます。
  2. データベース コードは、saveEmail などへの呼び出しごとに新しい接続を作成します。これは、ほとんどの時間をハンドシェイクと認証に費やします。呼び出し間で接続を維持するオブジェクトを用意するか、一度に複数のレコードを挿入することをお勧めします。
  3. ネットワークとデータベースの問題が完了すると、正規表現はおそらく\bその周りで処理できるため、マッチングのバックトラッキングが少なくなります.
  4. 一連の if not 'foo' in str: then if not 'blah' in str ... は不適切なコーディングです。最後のセグメントを 1 回抽出し、許可されていないすべての値 likesetを作成し、その like と比較することによって、複数の値に対してチェックします。また、最初に拡張子を小文字に変換すると、チェックが少なくなり、jpg か JPG かに関係なく機能することにも注意してください。frozensetignoredExtensions = set([jpg,png,gif])if not extension in ignoredExtensions
  5. 最後に、複数のコマンドラインでスレッド化せずに同じスクリプトを実行することを検討してください。異なる URL リストを調整することを除いて、スクリプト内にスレッドを作成する必要はありません。率直に言って、一連の URL リストをファイルに格納し、それぞれに対して個別のスクリプトを開始する方がはるかに簡単です。OS にマルチスレッド化を任せてください。OS の方が優れています。
于 2013-02-08T09:56:33.873 に答える