urlretrieve 沒有超時,需要通過socket來設置
socket.setdefaulttimeout(10)
而且還需要為他設置連接池,所以直接改用requests來下載文件
def download_file(self, url, filename): r = self.session.get(url, stream=True) with open(filename, 'wb') as f: for chunk in r.iter_content(chunk_size=512): if chunk: f.write(chunk)
寫原生爬蟲遇到問題 can`t start new thread 自己的機器上一直沒問題沒發現,到了別人的機器上暴漏出來了。
原因是原生的thread在執行完成后并沒有銷毀退出,而是進入了sleeping狀態,導致最后線程創建超出了允許的上限。其實通過修改Thread的初始化中的一些行為,可以使thread可以復用。
或者簡單點,使用線程池來解決
from concurrent.futures.thread import ThreadPoolExecutor def thread_run(target, args_list, max_thread=12): with ThreadPoolExecutor(max_thread) as executor: for arg in args_list: executor.submit(target, arg)
還有一個問題就是 Connection pool is full, discarding connection
可以進行如下設置
session.mount(prefix='', adapter=HTTPAdapter(pool_connections=1, pool_maxsize=36, max_retries=1))
但是在多線程情況下還是會出現 pool is full。我把maxsize設置的比 threads數稍大一點時,就沒有warning了,也可能是我代碼還有隱藏的問題。
也可能跟線程池有關,暫時沒看 線程池的源碼,如果這樣可以通過信號量來加鎖
from threading import Semaphore class AA(): sem = Semaphore(12) ... def getHtml(): sem.acquire() session.get() sem.release()
浙公網安備 33010602011771號