Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python使用循环对大型列表进行多处理_Python_Loops_Proxy_Multiprocessing_Python Requests - Fatal编程技术网

Python使用循环对大型列表进行多处理

Python使用循环对大型列表进行多处理,python,loops,proxy,multiprocessing,python-requests,Python,Loops,Proxy,Multiprocessing,Python Requests,老实说,我甚至不知道这个问题的标题是什么。我试图循环浏览大量URL,但一次只处理20个URL(20个基于我拥有多少代理)。但是我还需要在代理列表中循环,因为我正在处理URL。例如,它将从第一个URL和第一个代理开始,一旦它到达第21个URL,它将再次使用第一个代理。下面是我可怜的例子,如果有人能给我指出正确的方向,我将不胜感激 import pymysql.cursors from multiprocessing import Pool from fake_useragent import Us

老实说,我甚至不知道这个问题的标题是什么。我试图循环浏览大量URL,但一次只处理20个URL(20个基于我拥有多少代理)。但是我还需要在代理列表中循环,因为我正在处理URL。例如,它将从第一个URL和第一个代理开始,一旦它到达第21个URL,它将再次使用第一个代理。下面是我可怜的例子,如果有人能给我指出正确的方向,我将不胜感激

import pymysql.cursors
from multiprocessing import Pool
from fake_useragent import UserAgent

def worker(args):
    var_a, id, name, content, proxy, headers, connection = args
    print (var_a)
    print (id)
    print (name)
    print (content)
    print (proxy)
    print (headers)
    print (connection)
    print ('---------------------------')

if __name__ == '__main__':
    connection = pymysql.connect(
        host = 'host ',
        user = 'user',
        password = 'password',
        db = 'db',
        charset='utf8mb4',
        cursorclass=pymysql.cursors.DictCursor
    )

    ua = UserAgent()
    user_agent = ua.chrome
    headers = {'User-Agent' : user_agent}

    proxies = [
        'xxx.xxx.xxx.xxx:xxxxx',
        'xxx.xxx.xxx.xxx:xxxxx',
        'xxx.xxx.xxx.xxx:xxxxx',
        'xxx.xxx.xxx.xxx:xxxxx',
        'xxx.xxx.xxx.xxx:xxxxx',
        'xxx.xxx.xxx.xxx:xxxxx',
        'xxx.xxx.xxx.xxx:xxxxx',
        'xxx.xxx.xxx.xxx:xxxxx',
        'xxx.xxx.xxx.xxx:xxxxx',
        'xxx.xxx.xxx.xxx:xxxxx',
        'xxx.xxx.xxx.xxx:xxxxx',
        'xxx.xxx.xxx.xxx:xxxxx',
        'xxx.xxx.xxx.xxx:xxxxx',
        'xxx.xxx.xxx.xxx:xxxxx',
        'xxx.xxx.xxx.xxx:xxxxx',
        'xxx.xxx.xxx.xxx:xxxxx',
        'xxx.xxx.xxx.xxx:xxxxx',
        'xxx.xxx.xxx.xxx:xxxxx',
        'xxx.xxx.xxx.xxx:xxxxx'
    ]

    with connection.cursor() as cursor:
        sql = "SELECT id,name,content FROM table"
        cursor.execute(sql)
        urls = cursor.fetchall()

    var_a = 'static'

    data = ((var_a, url['id'], url['name'], url['content'], proxies[i % len(proxies)], headers, connection) for i, url in enumerate(urls))
    proc_num = 20
    p = Pool(processes=proc_num)
    results = p.imap(worker, data)
    p.close() 
    p.join()
请尝试以下代码:

for i in range(len(urls)):
    url = urls[i] # Current URL
    proxy = proxies[i % len(proxies)] # Current proxy
    # ...

您可以使用列表来存储新流程。当达到一定数量的项目时,为列表中的每个进程调用
join
。这将使您能够控制活动进程的数量

if __name__ == '__main__':  
    proc_num = 20
    proc_list = []
    for i, url in enumerate(urls):
        proxy = proxies[i % len(proxies)] 
        p = Process(target=worker, args=(url, proxy))
        p.start()
        proc_list.append(p)
        if i % proc_num == 0 or i == len(urls)-1: 
            for proc in proc_list: 
                proc.join()

如果您想要固定数量的活动进程,可以尝试
模块。只需修改
worker
定义即可接收元组

if __name__ == '__main__': 
    data = ((url, proxies[i % len(proxies)]) for i, url in enumerate(urls))
    proc_num = 20
    p = Pool(processes=proc_num)
    results = p.imap(worker, data)
    p.close() 
    p.join()

为了澄清问题,
worker
函数应该接收一个元组,然后将其解包

def worker(args):
    var_a, id, name, content, proxy, headers, connection = args
    print (var_a)
    ... etc ...

一次只生成20个进程(或列表中有多少代理)怎么样?当每个进程启动时,将其添加到计数器中。当它结束时将其移除。在for循环中,在执行之前检查计数器。我想我只是感到困惑。for循环不就是让所有过程同时启动吗?所以,如果我有1000个链接,它不会尝试启动1000个进程吗?如何让它一次只创建20个进程?我想我需要这样的东西(第一个答案),但如何在函数中输入代理,因为在答案中没有使用循环。他只是在地图上输入数组。我一直在测试你给我的代码,它在一定程度上起作用。但是我有一个while循环,当我发出请求时,它不会中断,直到请求通过(有时回接代理坏了,需要等待获得一个新的)。但如果发生这种情况,它似乎会等待while循环完成,然后再请求任何其他链接。我认为多处理的全部目的是能够同时多次调用同一个函数?也许我误解了它的工作原理。您可以使用
多处理.Pool
,它应该更平滑。也可以考虑在<>代码>请求中使用一个合理的超时时间(5到30秒)。我看到您正在将“数据”输入imap,但是如果我有更多的变量需要输入函数呢?我需要访问url[“名称”]、url[“id”]等。。。从URL。如何将这些变量添加到imap中是一个很小的困惑。你能更具体一点吗
url
是一个字符串,它没有任何键。但是,您可以修改
worker
的定义以接受任意数量的参数:
def worker(*args):
,或者构建一个“helper”函数将参数解压到
worker
,例如:
def helper(args):返回worker(*args)
是的,抱歉,URL只是一个示例。URL实际上是一个MySQL选择查询。因此,我需要能够从中选择列并将它们输入到函数中,以及代理(我在上面的示例中就是这样设置的)希望这更清楚一点。