2013-05-26 22 views
0

不知道這是否可能,花一些時間看看類似的問題,但仍不清楚。對於網站的URL列表,我需要以html爲起點。如何批量異步web請求使用Python中的理解執行?

我有一個包含這些URL列表的類和類返回一個自定義的迭代器,可以幫助我通過這些迭代,以獲取HTML(以下簡化)

class Url: 
    def __init__(self, url) 
     self.url = url 

    def fetchhtml(self) 
     import urllib2 
     response = urllib2.urlopen(self.url) 
     return response.read() 

class MyIterator: 
    def __init__(self, obj): 
     self.obj=obj 
     self.cnt=0 

    def __iter__(self): 
     return self 

    def next(self): 
     try: 
      result=self.obj.get(self.cnt) 
      self.cnt+=1 
      return result 
     except IndexError: 
      raise StopIteration 

class Urls: 
    def __init__(self, url_list = []): 
     self.list = url_list 

    def __iter__(self): 
     return MyIterator(self) 

    def get(self, index): 
     return self.list[index] 

2 - 我希望能夠使用像

url_list = [url1, url2, url3] 
urls = Urls(url_list) 
html_image_list = {url.url: re.search('@src="([^"]+)"', url.fetchhtml()) for url in urls} 

3 - 問題我已經是我想批的所有請求,而不是fetchhtml我的名單上依次操作,一旦他們這樣做,然後提取圖像列表。

有沒有辦法來實現這一點,也許使用線程和隊列?我無法看到如何使我的對象工作像這樣的列表理解沒有順序運行。也許這是錯誤的方式,但我只想批量處理由列表中的操作發起的長時間運行的請求或聽懂理解。 Thankyou提前

回答

1

您需要使用threadingmultiprocessing

另外,在Python3中,有concurrent.futures。 看看ThreadPoolExecutorProcessPoolExecutor

example in the docsThreadPoolExecutor確實幾乎完全你問:

import concurrent.futures 
import urllib.request 

URLS = ['http://www.foxnews.com/', 
     'http://www.cnn.com/', 
     'http://europe.wsj.com/', 
     'http://www.bbc.co.uk/', 
     'http://some-made-up-domain.com/'] 

# Retrieve a single page and report the url and contents 
def load_url(url, timeout): 
    conn = urllib.request.urlopen(url, timeout=timeout) 
    return conn.readall() 

# We can use a with statement to ensure threads are cleaned up promptly 
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor: 
    # Start the load operations and mark each future with its URL 
    future_to_url = {executor.submit(load_url, url, 60): url for url in URLS} 
    for future in concurrent.futures.as_completed(future_to_url): 
     url = future_to_url[future] 
     try: 
      data = future.result() 
     except Exception as exc: 
      print('%r generated an exception: %s' % (url, exc)) 
     else: 
      print('%r page is %d bytes' % (url, len(data))) 
  • 注:類似的功能,通過futures包PyPI上對於Python 2。
+0

謝謝科裏 - 這很有用(看看2.x版本),但我需要提供一個API,使用這種類型的邏輯,否則它是隱藏的。應該通過類似於第二點的理解來訪問它。 有沒有一種方法可以實現點2或替代方案?我在想某種程度上「骯髒」返回的url實例,之前是引發StopIteration,做你所描述的,然後重置迭代。 – user2422470