Python 如何在web抓取时维护同一主机的多个会话?

Python 如何在web抓取时维护同一主机的多个会话?,python,python-3.x,session,web-scraping,python-requests,Python,Python 3.x,Session,Web Scraping,Python Requests,我的网页抓取代码有问题。其要点如下: 我有一个代理池,并为每个代理初始化一个会话对象。之后,我将session对象传递给一个线程,该线程然后web抓取一个站点(在本例中为globenewswire.com)。我的问题在于一次用多个会话抓取同一个站点。当我有多个会话对象在多线程环境中运行时,就会出现错误。当我一次运行一个会话对象时,我完全没有问题 import time import requests import threading lock = threading.Lock() proxy_

我的网页抓取代码有问题。其要点如下:

我有一个代理池,并为每个代理初始化一个会话对象。之后,我将session对象传递给一个线程,该线程然后web抓取一个站点(在本例中为globenewswire.com)。我的问题在于一次用多个会话抓取同一个站点。当我有多个会话对象在多线程环境中运行时,就会出现错误。当我一次运行一个会话对象时,我完全没有问题

import time
import requests
import threading

lock = threading.Lock()
proxy_pool = []  # List of 11 proxies with format: "0.0.0.0:0000"
session_pool = []


def print_lock(stuff):
    with lock:
        print(stuff)


def initialize_session(proxy):
    global session_pool
    proxiez = {"http": "http://" + proxy, "https": "http://" + proxy}
    s = requests.Session()
    s.mount('https://globenewswire.com', HTTPAdapter(pool_connections=1, pool_maxsize=11))
    s.proxies = proxiez
    while True:
        try:
            r = s.get('http://globenewswire.com/Search', headers={'headers': 'here'})
            if r.status_code == 200:
                break
            else:
                print_lock('r.status_code =', str(r.status_code), 'for proxy:', proxy)
        except Exception as e:
            print_lock('Error for proxy:', proxy + '. Error:', str(e))
        time.sleep(1)
    with lock:
        session_pool.append(s)
        print('Created Session now in session_pool with proxy: ' + proxy + '.')


startup_thread_list = []
for proxie in proxy_pool:
    startup_thread = threading.Thread(target=initialize_session, args=(proxie,))
    startup_thread_list.append(startup_thread)
    startup_thread.daemon = True
    startup_thread_list.append(startup_thread)
    startup_thread.start()
for thread in startup_thread_list:
    thread.join()
print('Set up all sessions.')


def remove_session():
    global session_pool
    while True:
        with lock:
            if len(session_pool) == 0:
                session_waited = 'yes'
            else:
                session = session_pool[0]
                session_pool.remove(session)
                break
        time.sleep(0.1)
    return session

while True:
    sesh = remove_session()
    doStuffwithSessionthread = threading.Thread(target=doStuff, args=(sesh,))
    doStuffwithSessionthread.daemon = True
    doStuffwithSessionthread.start()
    # Submit the session to only one thread
    # the thread then returns that session to the session_pool as its final task.
    time.sleep(4)
有趣的是,我尝试为代理池中的每个代理打开一个单独的Python解释器,只向每个解释器的池传递一个代理。我有效地将会话对象的数量限制为每个解释器一个。我能够同时运行11名口译员,没有任何问题。然而,如果我尝试在一个解释器中运行11个会话,我会得到比状态代码200s更多的错误。这使我相信我的请求模块或我自己的代码存在线程问题

请求建议每个线程只运行一个会话对象。我知道,对于我拥有的每个会话对象,我最多只运行一个线程,但由于某些原因,我的https请求返回时往往会出现错误

如果在解释器中的任何时候只有一个会话对象发出请求,但一旦多个会话对象同时发出请求,就会像明天一样吐出错误,那么该代码也可以完美地工作

这困扰了我一段时间,有人知道会发生什么吗?如果我还需要澄清什么,请告诉我