Python使用循环对大型列表进行多处理
老实说,我甚至不知道这个问题的标题是什么。我试图循环浏览大量URL,但一次只处理20个URL(20个基于我拥有多少代理)。但是我还需要在代理列表中循环,因为我正在处理URL。例如,它将从第一个URL和第一个代理开始,一旦它到达第21个URL,它将再次使用第一个代理。下面是我可怜的例子,如果有人能给我指出正确的方向,我将不胜感激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
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选择查询。因此,我需要能够从中选择列并将它们输入到函数中,以及代理(我在上面的示例中就是这样设置的)希望这更清楚一点。