繁体   English   中英

为什么我不能在python中使用多线程加速爬网?

[英]Why can I not speed up crawling with multithreading in python?

在下方,您可以看到我的履带的蓝图。 我以为我可以通过多线程来加快速度,但是我做不到。 通常,当我加载页面时,Web服务器速度很慢,然后最好爬网另一个使用多线程加载速度更快的网页。 但这并没有更快。 为什么?

def start_it():
    while(True):
        get_urls()

def get_urls():
   response = urllib2.urlopen(url)
   page_source = str(response.read())

pool = ThreadPool(10)

pool.map(start_it())

好吧,我测试了线程是否并行运行,而不是:/我在做什么错?

def start_it():

    x = random.random()
    while(True):
        get_urls(x)

def get_urls(x):
    print(x)

pool = ThreadPool(10)

pool.map(start_it())

我知道这一点,因为输出始终是相同的:

0.1771815430790964
0.1771815430790964
0.1771815430790964
0.1771815430790964
0.1771815430790964
0.1771815430790964
0.1771815430790964

您需要提供一个可迭代的pool.map()

目前,您正在运行start_it() ,它基本上一个接一个地运行所有调用。 我不知道您使用的是哪种ThreadPool实现,但您可能需要执行以下操作:

pool.map(get_urls, list_of_urls)

不离题,但是异步IO也是解决您的问题的理想选择。 您可以使用一个名为asyncio的惊人库,该库最近已添加到python 3.4中。 对于较旧的版本,可以使用trolliusTwisted

如果实际发布的代码运行,则不应执行pool.map(start_it()) ,因为这start_it 将结果传递给start_it 之前调用pool.map 相反,你必须通过start_it没有任何()pool.map(start_it) 您可能还需要另一个参数(将值传递给start_it)。

您可以尝试以下示例,它似乎对我有用。

import json
import multiprocessing.pool
import time
import urllib2

def run(no):
    for n in range(3):
        f = urllib2.urlopen("http://time.jsontest.com")
        data = json.loads(f.read())
        f.close()
        print("thread %d: %s" % (no, data))
        time.sleep(1)

pool = multiprocessing.pool.ThreadPool(3)
pool.map(run, range(3))

您也可以使用multiprocess.Process ,例如:

import multiprocessing
import time
import os

def run(jobno):
    for n in range(3):
        print("job=%d pid=%d" % (jobno, os.getpid()))
        time.sleep(1)

jobs = []
for n in range(3):
    p = multiprocessing.Process(target=run, args=[n])
    jobs.append(p)

map(lambda x: x.start(), jobs)
map(lambda x: x.join(), jobs)

输出示例:

job=0 pid=18347
job=1 pid=18348
job=2 pid=18349
job=0 pid=18347
job=2 pid=18349
job=1 pid=18348
job=2 pid=18349
job=0 pid=18347
job=1 pid=18348

multiprocessing模块下的所有内容都使用进程而不是线程,而线程实际上是并行的。 请注意,可能存在一些问题(与在同一过程中将它们作为线程运行相比)。

我认为这种方式可以真正并行运行。 我的爬行速度大大提高了。 太棒了;)

import multiprocessing
import random

def worker():
    """worker function"""

    x = random.random()*10
    x = round(x)
    while(True):
        print(x , ' Worker')

if __name__ == '__main__':
    jobs = []
    for i in range(5):
        p = multiprocessing.Process(target=worker)
        jobs.append(p)
        p.start()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM