2013-05-26 23 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