0

我有这个简单的代码,它通过以下方式获取页面urllib

browser_list= ['Chrome','Mozilla','Safari','Internet Explorer','Opera']
user_string_url="http://www.useragentstring.com/pages/"
for eachBrowser in browser_list:
    result= urllib2.urlopen(urljoin(user_string_url,eachBrowser))

现在我可以通过读取结果,result.read()但我想知道是否所有这些功能都可以在for循环之外完成。因为其他要获取的 URL 会等到所有结果都处理完。

我想在循环result外处理。for这可以做到吗?

4

5 回答 5

3

其中一种方法可能是将结果作为字典。你可以做的是:结果 = {}

for eachBrowser in browser_list:
result[eachBrowser]= urllib2.urlopen(urljoin(user_string_url,eachBrowser))

并在循环外使用 result[BrowserName] 。希望这可以帮助。

于 2013-07-27T18:26:37.813 回答
1

如果您只是想访问循环外的所有结果,只需将所有结果附加到数组或字典中,如上述答案。

或者,如果您想加快任务速度,请尝试多线程

import threading
class myThread (threading.Thread):
    def __init__(self, result):
        threading.Thread.__init__(self)
        self.result=result
    def run(self):
       // process your result(as self.result) here

browser_list= ['Chrome','Mozilla','Safari','Internet Explorer','Opera']
user_string_url="http://www.useragentstring.com/pages/"
for eachBrowser in browser_list:
    result= urllib2.urlopen(urljoin(user_string_url,eachBrowser))
    myThread(result).start() // it will start processing result on another thread and continue loop without any waiting

它是一种简单的多线程方法。根据您的结果处理,它可能会中断。在尝试之前,请考虑阅读文档和一些示例。

于 2013-07-27T19:02:00.303 回答
0

您可以为此使用线程:

import threading
import urllib2
from urlparse import urljoin

def worker(url):
    res = urllib2.urlopen(url)
    data = res.read()
    res.close()

browser_list = ['Chrome', 'Mozilla', 'Safari', 'Internet Explorer', 'Opera']
user_string_url='http://www.useragentstring.com/'
for browser in browser_list:
    url = urljoin(user_string_url, browser)
    threading.Thread(target=worker,args=[url]).start()

 # wait for everyone to complete
 for thread in threading.enumerate():
     if thread == threading.current_thread(): continue
     thread.join()
于 2013-07-27T19:03:12.560 回答
0

你在使用 python3 吗?如果是这样,你可以使用futures来完成这个任务:

from urllib.request import urlopen
from urllib.parse import urljoin
from concurrent.futures import ThreadPoolExecutor

browser_list = ['Chrome','Mozilla','Safari','Internet+Explorer','Opera']
user_string_url = "http://www.useragentstring.com/pages/"

def process_request(url, future):
    print("Processing:", url)
    print("Reading data")
    print(future.result().read())

with ThreadPoolExecutor(max_workers=10) as executor:
    submit = executor.submit
    for browser in browser_list:
        url = urljoin(user_string_url, browser) + '/'
        submit(process_request, url, submit(urlopen, url))
于 2013-07-27T19:03:21.580 回答
0

你也可以用产量来做到这一点:

def collect_browsers():
    browser_list= ['Chrome','Mozilla','Safari','Internet Explorer','Opera']
    user_string_url="http://www.useragentstring.com/pages/"
    for eachBrowser in browser_list:
        yield eachBrowser, urllib2.urlopen(urljoin(user_string_url,eachBrowser))


def process_browsers():
   for browser, result in collect_browsers():
       do_something (result)

这仍然是一个同步调用(浏览器 2 在处理浏览器 1 之前不会触发),但您可以将处理结果的逻辑与管理连接的逻辑分开。您当然也可以使用线程来异步处理处理,无论是否有产量

编辑

只需重新阅读 OP 并且应该重复该 yield 不提供多线程异步执行,以防我在第一个答案中不清楚!

于 2013-07-28T02:15:39.567 回答