python实现多线程采集的2个代码例子

  

下面是详细的攻略:

Python实现多线程采集

前言

对于一些需要收集数据的任务,并发的采集方式无疑是对效率的一大提升。Python语言提供了多线程编程的支持,本文将会介绍两种使用Python实现多线程采集的方式并提供相应的代码。

代码实现

代码一

第一种实现方式相对来说比较简单理解,我们可以直接使用Thread类来创建新的线程并运行。

import threading
import requests

def main():
    urls = ["http://example.com/", 
            "http://example.com/news", 
            "http://example.com/about", 
            "http://example.com/contact",
            "http://example.com/sitemap",
            "http://example.com/blog",
            "http://example.com/jobs",
            "http://example.com/feedback"]

    threads = []

    for url in urls:
        t = threading.Thread(target=fetch_url, args=(url,))
        threads.append(t)
        t.start()

    for t in threads:
        t.join()

def fetch_url(url):
    print("Fetching {0}".format(url))
    try:
        r = requests.get(url)
        print("{0}: {1}".format(url, r.status_code))
    except requests.exceptions.RequestException as e:
        print("{0}: {1}".format(url, e))

使用上述代码,简单来说,我们首先定义了一个列表urls,并在遍历该列表的过程中,创建了多个线程,每个线程都调用了fetch_url函数,并传入了当前的URL。接着,我们在主线程内通过join等待其他线程的结束。

代码二

另外一种实现方式相对来说更加高级,可以同时限制线程数量来进一步提升效率,我们可以使用Python的线程池来实现。

import concurrent.futures
import requests

def main():
    urls = ["http://example.com/", 
            "http://example.com/news", 
            "http://example.com/about", 
            "http://example.com/contact",
            "http://example.com/sitemap",
            "http://example.com/blog",
            "http://example.com/jobs",
            "http://example.com/feedback"]

    with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
        future_to_url = {executor.submit(fetch_url, url): url for url in urls}
        for future in concurrent.futures.as_completed(future_to_url):
            url = future_to_url[future]
            try:
                data = future.result()
                print("{0}: {1}".format(url, data))
            except Exception as exc:
                print("{0}: {1}".format(url, exc))

def fetch_url(url):
    print("Fetching {0}".format(url))
    try:
        r = requests.get(url)
        return r.status_code
    except requests.exceptions.RequestException as e:
        return str(e)

使用以上代码,我们可以看到,在主函数内,我们首先定义了一个URL列表urls,并使用线程池ThreadPoolExecutor创建了一个最大线程数为5的线程池。随后,我们在使用submit方法向线程池提交任务时,还为每个任务使用了一个dict来存储其对应的URL地址,方便我们后续的输出。最后,我们在对future进行as_completed迭代的过程中获取了每个任务返回的结果。

总结

以上两种多线程采集Python代码的方式并不是唯一的选择,而是较为常用且简便的方式之一。通过合理使用多线程的方式来提升程序的效率,是Python程序员们需要重点考虑的一项工作。

相关文章