Python 如何在web抓取时维护同一主机的多个会话?
我的网页抓取代码有问题。其要点如下: 我有一个代理池,并为每个代理初始化一个会话对象。之后,我将session对象传递给一个线程,该线程然后web抓取一个站点(在本例中为globenewswire.com)。我的问题在于一次用多个会话抓取同一个站点。当我有多个会话对象在多线程环境中运行时,就会出现错误。当我一次运行一个会话对象时,我完全没有问题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_
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请求返回时往往会出现错误
如果在解释器中的任何时候只有一个会话对象发出请求,但一旦多个会话对象同时发出请求,就会像明天一样吐出错误,那么该代码也可以完美地工作
这困扰了我一段时间,有人知道会发生什么吗?如果我还需要澄清什么,请告诉我