Python 多处理减慢了我的网络爬虫?

Python 多处理减慢了我的网络爬虫?,python,multiprocessing,web-crawler,Python,Multiprocessing,Web Crawler,我想下载20个csv文件,所有文件的大小都在一起-5MB 以下是我的代码的第一个版本: import os from bs4 import BeautifulSoup import urllib.request import datetime def get_page(url): try: return urllib.request.urlopen(url).read() except: print("[warn] %s" % (url))

我想下载20个csv文件,所有文件的大小都在一起-
5MB

以下是我的代码的第一个版本:

import os
from bs4 import BeautifulSoup
import urllib.request
import datetime

def get_page(url):
    try:
        return urllib.request.urlopen(url).read()
    except:
        print("[warn] %s" % (url))
        raise

def get_all_links(page):
    soup = BeautifulSoup(page)
    links = []
    for link in soup.find_all('a'):
        url = link.get('href')
        if '.csv' in url:
            return url
    print("[warn] Can't find a link with CSV file!")

def get_csv_file(company):
    link = 'http://finance.yahoo.com/q/hp?s=AAPL+Historical+Prices'
    g = link.find('s=')
    name = link[g + 2:g + 6]
    link = link.replace(name, company)
    urllib.request.urlretrieve(get_all_links(get_page(link)), os.path.join('prices', company + '.csv'))
    print("[info][" + company + "] Download is complete!")

if __name__ == "__main__":
    start = datetime.datetime.now()
    security_list = ["AAPL", "ADBE", "AMD", "AMZN", "CRM", "EXPE", "FB", "GOOG", "GRPN", "INTC", "LNKD", "MCD", "MSFT", "NFLX", "NVDA", "NVTL", "ORCL", "SBUX", "STX"]
    for security in security_list:
        get_csv_file(security)

    end = datetime.datetime.now()
    print('[success] Total time: ' + str(end-start))
此代码在1.2分钟内下载20个csv文件,其大小为所有文件的大小-
5MB

然后我尝试使用
多处理
来加快下载速度。
以下是第2版:

if __name__ == "__main__":
    import multiprocessing
    start = datetime.datetime.now()

    security_list = ["AAPL", "ADBE", "AMD", "AMZN", "CRM", "EXPE", "FB", "GOOG", "GRPN", "INTC", "LNKD", "MCD", "MSFT", "NFLX", "NVDA", "NVTL", "ORCL", "SBUX", "STX"]
    for i in range(20):
        p = multiprocessing.Process(target=hP.get_csv_files([index] + security_list), args=(i,))
        p.start()

    end = datetime.datetime.now()
    print('[success] Total time: ' + str(end-start))
但是,不幸的是,版本2在2.4分钟内下载了20个csv文件,大小相当于所有文件的总和-
5MB

为什么
多处理
会减慢我的程序?
我做错了什么?
比现在更快下载这些文件的最佳方式是什么?


谢谢?

我不知道您在示例中试图从流程开始做什么(我认为您有一些拼写错误)。我想你想要这样的东西:

processs = []
for security in security_list:
    p = multiprocessing.Process(target=get_csv_file, args=(security,))
    p.start()
    processs.append(p)

for p in processs:
    p.join()
您可以通过这种方式对安全性进行迭代,为每个安全性名称创建一个新进程,并将该进程放入列表中

启动所有进程后,使用join循环它们并等待它们完成

还有一种更简单的方法,使用池及其并行映射实现

pool = multiprocessing.Pool(processes=5)
pool.map(get_csv_file, security_list)

创建一个进程池(如果省略参数,它将创建一个等于处理器计数的数字),然后使用map将函数应用于列表中的每个元素。游泳池会照顾剩下的人

我不知道您在示例中试图从流程开始做什么(我认为您有一些拼写错误)。我想你想要这样的东西:

processs = []
for security in security_list:
    p = multiprocessing.Process(target=get_csv_file, args=(security,))
    p.start()
    processs.append(p)

for p in processs:
    p.join()
您可以通过这种方式对安全性进行迭代,为每个安全性名称创建一个新进程,并将该进程放入列表中

启动所有进程后,使用join循环它们并等待它们完成

还有一种更简单的方法,使用池及其并行映射实现

pool = multiprocessing.Pool(processes=5)
pool.map(get_csv_file, security_list)

创建一个进程池(如果省略参数,它将创建一个等于处理器计数的数字),然后使用map将函数应用于列表中的每个元素。游泳池会照顾剩下的人

首先,您没有得到太多的加速,因为下载数据是一项IO密集型任务,可以由单个进程/线程轻松处理。其次,创建流程的成本很高。更好的方法是创建一个进程池(就像一个线程池),并在任务到来时不断分派it任务。在Windows上创建进程比*ix要昂贵得多。首先,下载数据是一项IO密集型任务,单进程/线程可以轻松处理,因此速度不会太快。其次,创建流程的成本很高。一个更好的方法是创建一个进程池(就像线程池一样),并在任务到来时不断分派it任务。在Windows上创建进程比*ix要昂贵得多。池:类型错误:无法隐式地将“list”对象转换为str?我在我的电脑上测试了这个版本,它可以正常工作。您使用什么Python版本?你能给出完整的回溯吗?我使用的是python 3,这是一个伪错误,这里有一个新错误:
回溯(最近一次调用):文件“C:\Users\******\Documents\***************************.py”,第134行,在pool.map(hP.get\u csv\u文件([index]+安全列表),[index]+安全列表)文件“C:\Python33\lib\multiprocessing\pool.py”,第228行,在map return self.\u map\u async(func,iterable,mapstar,chunksize).get()文件“C:\Python33\lib\multiprocessing\pool.py”,第564行,在get raise self.\u value TypeError:“NoneType”对象不可调用
在将函数传递给map时不要调用,只使用函数的名称(get\u csv\u文件,不带(…)。此外,您似乎正在使用另一个函数,它同时将所有证券作为参数。这不是你使用地图的方式。指定给map的函数应只进行一项计算,map将该函数应用于所有需要处理的项。对于pool:TypeError:无法将“list”对象隐式转换为str?我在我的电脑上测试了这个版本,它可以正常工作。您使用什么Python版本?你能给出完整的回溯吗?我使用的是python 3,这是一个伪错误,这里有一个新错误:
回溯(最近一次调用):文件“C:\Users\******\Documents\***************************.py”,第134行,在pool.map(hP.get\u csv\u文件([index]+安全列表),[index]+安全列表)文件“C:\Python33\lib\multiprocessing\pool.py”,第228行,在map return self.\u map\u async(func,iterable,mapstar,chunksize).get()文件“C:\Python33\lib\multiprocessing\pool.py”,第564行,在get raise self.\u value TypeError:“NoneType”对象不可调用
在将函数传递给map时不要调用,只使用函数的名称(get\u csv\u文件,不带(…)。此外,您似乎正在使用另一个函数,它同时将所有证券作为参数。这不是你使用地图的方式。给定给map的函数应该只进行一项计算,map将把该函数应用于所有需要处理的项。