0

不确定这是否可能,花一些时间看看类似的问题,但仍不清楚。对于网站 url 列表,我需要以 html 为起点。

我有一个包含这些 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 - 我希望能够使用 like

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 在我的列表上按顺序操作,一旦完成,然后提取图像列表。

有没有办法实现这一点,也许使用线程和队列?如果不按顺序运行,我看不到如何使我的对象的列表理解像这样工作。也许这是错误的方式,但我只想批处理由列表或字典理解中的操作发起的长时间运行的请求。先感谢您

4

1 回答 1

1

您需要使用threadingmultiprocessing

此外,在 Python3 中,还有concurrent.futures. 看看ThreadPoolExecutorProcessPoolExecutor

文档中的示例ThreadPoolExecutor几乎完全符合您的要求:

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 也可以使用类似的功能。
于 2013-05-26T16:30:03.513 回答