【问题标题】:Python - Multiple HTTP requests too slowPython - 多个 HTTP 请求太慢
【发布时间】:2016-09-21 12:51:07
【问题描述】:

我是 Python 编程新手。

我正在尝试解析来自 Instagram 的 HTTP 请求,以使用正则表达式查找特定单词。

我使用了多处理,但它仍然很慢。我知道我的代码可能看起来很愚蠢,但这是我最好的。

我做错了什么让它变慢了?我需要让它更快地发送多个 HTTP 请求。

import requests
import re 
import time
from bs4 import BeautifulSoup
from multiprocessing.dummy import Pool  
from multiprocessing import cpu_count


Nthreads = cpu_count()*2
pool = Pool(Nthreads)


f = open('full.txt','r')
fw = open('out.txt', 'w')


def findSnap(bio):
    regex = 'content=".*sn[a]*p[a-z]*\s*[^a-z0-9].*'
    snap = re.findall(regex, bio)
    if not snap:
        return None
    else:
        afterSnap = re.sub('content=".*sn[a]*p[a-z]*\s*[^a-z0-9]*\s*','',snap[0])
        if afterSnap:
            afterSnap = re.findall('[\w_\.-]*',afterSnap)[0]
            sftS = afterSnap.split()
            if sftS:
                return sftS[0]
            return None
        return None

def loadInfo(url):
    #print 'Loading data..'
    st = time.time
    try:
        page = requests.get(url).text.lower()
    except Exception as e:
        print('Something is wrong!')
        return None


    snap = findSnap(page)
    if snap:
        fw.write(snap + '\n')
        fw.flush()
        print(snap)
    else:
        return None
    return snap

start = time.time()
names = f.read().splitlines()
baseUrl = 'https://instagram.com/'
urls = map(lambda x: baseUrl + x, names)

pool.map(loadInfo, urls)
finish = time.time()

print((finish- start)/60)
fw.close()

【问题讨论】:

  • 那么时间结果是多少?
  • “但还是很慢”。相比什么?也许您发出请求的服务器很慢,或者您的互联网连接?然后你可以随心所欲地加速脚本,但这对你没有帮助。请先尝试找出慢的部分。
  • 顺便说一句,为什么线程数是 CPU 内核数的两倍?
  • @Evert 说了什么,而且,请告诉您您期望程序有多快,它实际上有多快,以及您的数据集有多大(即full.txt 中的行数)。

标签: python regex python-2.7 python-3.x


【解决方案1】:

正如一些人所说,也许我们需要更多关于您的时间、您期望什么以及您为什么期望的详细信息。因为您的应用程序的执行时间可能涉及很多因素,而不仅仅是您的代码,因为您的应用程序依赖于第三方资源。

无论如何,我已经看到您使用的是multiprocessing.dummy,这只是threading 模块[1] 的包装。根据其文档,它似乎不是您可以用来同时运行常规 Python 代码的最佳模块[2]:

CPython 实现细节:在 CPython 中,由于 Global 解释器锁,一次只能有一个线程执行Python代码 (即使某些面向性能的库可能会克服 这个限制)。如果您希望您的应用程序更好地利用 多核机器的计算资源,建议您 使用多处理或 concurrent.futures.ProcessPoolExecutor。 但是,如果要运行,线程仍然是合适的模型 同时执行多个 I/O 密集型任务。

确实,在您的情况下,您正在执行 I/O 操作,但处理正则表达式也是一项繁重的任务。

正如文中所说,可以尝试使用不同的池实现 在multiprocessing 模块中,而不是dummy,或者您也可以在concurrent.futures.ProcessPoolExecutor 中。

【讨论】:

    猜你喜欢
    • 2015-12-30
    • 1970-01-01
    • 2020-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多