【问题标题】:Run Parallel Request session in python在 python 中运行并行请求会话
【发布时间】:2019-07-19 11:05:13
【问题描述】:

我正在尝试打开多个 Web 会话并将数据保存到 CSV,已经使用 for loop 和 requests.get 选项编写了我的代码,但是访问 90 个 Web 位置需要很长时间。谁能让我知道整个过程如何为 loc_var 并行运行:

代码运行正常,只是loc_var的问题一一运行,耗时很长。

想要并行访问所有的for循环loc_var URL并进行CSV的写操作

以下是代码:

import pandas as pd
import numpy as np
import os
import requests
import datetime
import zipfile
t=datetime.date.today()-datetime.timedelta(2)
server = [("A","web1",":5000","username=usr&password=p7Tdfr")]
'''List of all web_ips'''
web_1 = ["Web1","Web2","Web3","Web4","Web5","Web6","Web7","Web8","Web9","Web10","Web11","Web12","Web13","Web14","Web15"]
'''List of All location'''
loc_var =["post1","post2","post3","post4","post5","post6","post7","post8","post9","post10","post11","post12","post13","post14","post15","post16","post17","post18"]

for s,web,port,usr in server:
    login_url='http://'+web+port+'/api/v1/system/login/?'+usr
    print (login_url)
    s= requests.session()
    login_response = s.post(login_url)
    print("login Responce",login_response)
    #Start access the Web for Loc_variable
    for mkt in loc_var:
        #output is CSV File
        com_actions_url='http://'+web+port+'/api/v1/3E+date(%5C%22'+str(t)+'%5C%22)and+location+%3D%3D+%27'+mkt+'%27%22&page_size=-1&format=%22csv%22'
        print("com_action_url",com_actions_url)
        r = s.get(com_actions_url)
        print("action",r)
        if r.ok == True:            
            with open(os.path.join("/home/Reports_DC/", "relation_%s.csv"%mkt),'wb') as f:
                f.write(r.content)  

        # If loc is not aceesble try with another Web_1 List
        if r.ok == False:
            while r.ok == False:
                for web_2 in web_1:
                    login_url='http://'+web_2+port+'/api/v1/system/login/?'+usr
                    com_actions_url='http://'+web_2+port+'/api/v1/3E+date(%5C%22'+str(t)+'%5C%22)and+location+%3D%3D+%27'+mkt+'%27%22&page_size=-1&format=%22csv%22'
                    login_response = s.post(login_url)
                    print("login Responce",login_response)
                    print("com_action_url",com_actions_url)
                    r = s.get(com_actions_url)
                    if r.ok == True:            
                        with open(os.path.join("/home/Reports_DC/", "relation_%s.csv"%mkt),'wb') as f:
                            f.write(r.content)  
                        break

【问题讨论】:

  • 我猜你是贴jupyter笔记本吧?

标签: python multithreading pandas asynchronous python-requests


【解决方案1】:

您可以采用多种方法来发出并发 HTTP 请求。我使用的两个是 (1) 使用 concurrent.futures.ThreadPoolExecutor 的多个线程或 (2) 使用 asyncio/aiohttp 异步发送请求。

要使用线程池并行发送请求,您首先要生成一个要并行获取的 URL 列表(在您的情况下生成 login_urlscom_action_urls 的列表),然后您将同时请求所有 URL,如下所示:

from concurrent.futures import ThreadPoolExecutor
import requests

def fetch(url):
    page = requests.get(url)
    return page.text
    # Catch HTTP errors/exceptions here

pool = ThreadPoolExecutor(max_workers=5)

urls = ['http://www.google.com', 'http://www.yahoo.com', 'http://www.bing.com']  # Create a list of urls

for page in pool.map(fetch, urls):
    # Do whatever you want with the results ...
    print(page[0:100])

使用 asyncio/aiohttp 通常比上面的线程方法更快,但学习曲线更复杂。这是一个简单的例子(Python 3.7+):

import asyncio
import aiohttp

urls = ['http://www.google.com', 'http://www.yahoo.com', 'http://www.bing.com']

async def fetch(session, url):
    async with session.get(url) as resp:
        return await resp.text()
        # Catch HTTP errors/exceptions here

async def fetch_concurrent(urls):
    loop = asyncio.get_event_loop()
    async with aiohttp.ClientSession() as session:
        tasks = []
        for u in urls:
            tasks.append(loop.create_task(fetch(session, u)))

        for result in asyncio.as_completed(tasks):
            page = await result
            #Do whatever you want with results
            print(page[0:100])

asyncio.run(fetch_concurrent(urls))

但除非您要发出大量请求,否则线程方法可能就足够了(并且更容易实现)。

【讨论】:

  • 我知道这是旧的,但你为什么将最大工人数设置为 5?您介意分享一下我们如何找出设置它的位置吗?除了反复试验?让最大工作人员空白将性能从 140 秒提高到 30 秒
  • 我已经很久没有这样做了,但我猜这是基于不想太快发送请求? (当时我正在编写很多脚本来从网站上抓取数据,并且需要限制请求的数量以防止被阻止)......但是,是的,你可能是对的,一般来说,并不总是是限制并发请求数的原因,并且没有限制会更快
  • link 对于其他发现此问题的人来说,这是一个极其复杂的长答案。如果您想了解更多信息,请阅读上面的链接。但是 TLDR 我认为最好不要指定,除非您有需要它的高级实现
猜你喜欢
  • 2020-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-20
  • 2013-03-19
  • 1970-01-01
相关资源
最近更新 更多