0

役に立たない変数名と不必要に肥大化したコードを失礼しますが、私はこれをすばやくまとめただけで、まだ最適化または整理する時間がありませんでした。

このプログラムを作成して、友​​人と送信したすべての画像を、URLのメッセージログを解析してWebカメラ写真共有サービス(321cheese.com)を使用して相互にダンプしました。問題は、私のマルチスレッドが機能していないように見えることです。

コードの下部に、コメントアウトされた非マルチスレッドのダウンロード方法が表示されます。これにより、常に正しい結果(この場合は121枚の写真)が生成されます。しかし、このアクションを新しいスレッドに送信しようとすると、プログラムは112枚の写真、90枚、115枚の写真などをダウンロードすることがありますが、正しい結果が得られないことがあります。

なぜこれが問題を引き起こすのでしょうか?同時スレッドの数(およびその方法)を制限する必要がありますか?

import urllib
import thread

def getName(input):
    l = input.split(".com/")
    m = l[1]
    return m

def parseMessages():
    theFile = open('messages.html', 'r')
    theLines = theFile.readlines()
    theFile.close()
    theNewFile = open('new321.txt','w')
    for z in theLines:
        if "321cheese" in z:
            theNewFile.write(z)
    theNewFile.close()

def downloadImage(inputURL):
    urllib.urlretrieve (inputURL, "./grabNew/" + d)

parseMessages()

f = open('new321.txt', 'r')
lines = f.readlines()
f.close()

g = open('output.txt', 'w')

for x in lines:
  a = x.split("<a href=\"")
  b = a[1].split("\"")
  c = b[0]
  if ".png" in c:
    d = getName(c)
    g.write(c+"\n")
    thread.start_new_thread( downloadImage, (c,) )
    ##downloadImage(c)

g.close()
4

2 に答える 2

1

解析が正しく機能していることを確認しましたか?

また、起動するスレッドが多すぎます。

そして最後に...Pythonのスレッドは偽物です!実際の並列処理が必要な場合はマルチプロセッシングモジュールを使用しますが、イメージはおそらくすべて同じサーバーからのものであるため、同じサーバーで同時に100の接続を開くと、ファイアウォールが接続を切断し始める可能性があります。

于 2012-12-03T00:05:14.250 に答える
1

コードには複数の問題があります。

主な問題はd、複数のスレッドでのグローバル名の使用です。これを修正するには、名前を引数として明示的にに渡しますdownloadImage()

同時ダウンロードの数を制限する簡単な方法(コード単位)は、concurrent.futures(Python 2で利用可能futures)またはmultiprocessing.Pool:を使用することです。

#!/usr/bin/env python
import urllib
from multiprocessing import Pool
from posixpath import basename
from urllib import unquote
from urlparse import urlsplit


download_dir = "grabNew"

def url2filename(url):
    return basename(unquote(urlsplit(url).path).decode('utf-8'))

def download_image(url):
    filename = None
    try:
        filename = os.path.join(download_dir, url2filename(url))
        return urllib.urlretrieve(url, filename), None
    except Exception as e:
        return (filename, None), e

def main():
    pool = Pool(processes=10)
    for (filename, headers), error in pool.imap_unordered(download_image, get_urls()):
        pass # do something with the downloaded file or handle an error

if __name__ == "__main__":
   main()
于 2012-12-03T01:43:52.123 に答える