python 多线程并行处理 Python多线程并发时出现503错误的最佳处理
目录
- 一、503 错误产生的缘故
- 二、503 错误处理的最佳操作
- (一)合理控制并发线程数量
- (二)设置合理的请求间隔
- (三)使用代理服务器和用户代理
- (四)重试机制
- 三、综合操作案例
- 四、拓展资料
一、503 错误产生的缘故
在 HTTP 协议中,503 错误表示服务器当前无法处理请求,通常是由于服务器暂时过载或维护。在多线程爬虫场景下,503 错误可能由下面内容几种缘故引起:
- 服务器负载过高:当多个线程同时向服务器发送请求时,服务器可能因负载过高而拒绝部分请求,返回 503 错误。
- 请求频率过快:如果爬虫的请求频率超过了服务器的处理能力,服务器可能会认为这是一种攻击行为,从而返回 503 错误。
- 服务器配置难题:某些服务器可能配置了特定的防护机制,如防火墙或反爬虫策略,当检测到异常请求时会返回 503 错误。
- 网络难题:网络不稳定或代理服务器故障也可能导致 503 错误。
二、503 错误处理的最佳操作
(一)合理控制并发线程数量
过多的并发线程会增加服务器的负载,导致 503 错误。因此,合理控制并发线程的数量是避免 503 错误的关键。可以通过设置线程池来限制并发线程的数量。
import concurrent.futuresimport requestsdef fetch_url(url): try: response = requests.get(url) response.raise_for_status() return response.text except requests.exceptions.HTTPError as e: if e.response.status_code == 503: print(f”503 error occurred for url}”) Handle 503 error else: raisedef main(): urls = [“http://example.com/page1”, “http://example.com/page2″, …] max_workers = 10 控制并发线程数量 with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor: futures = [executor.submit(fetch_url, url) for url in urls] for future in concurrent.futures.as_completed(futures): try: data = future.result() Process data except Exception as e: print(f”Error: e}”)if __name__ == “__main__”: main()
(二)设置合理的请求间隔
为了避免因请求频率过快导致的 503 错误,可以在请求之间设置合理的间隔时刻。这可以通过在请求代码中添加 <font style="color:rgba(0, 0, 0, 0.9);background-color:rgba(0, 0, 0, 0.03);">time.sleep()</font>
来实现。
import timeimport requestsdef fetch_url(url): try: response = requests.get(url) response.raise_for_status() return response.text except requests.exceptions.HTTPError as e: if e.response.status_code == 503: print(f”503 error occurred for url}”) Handle 503 error else: raisedef main(): urls = [“http://example.com/page1”, “http://example.com/page2”, …] for url in urls: fetch_url(url) time.sleep(1) 设置请求间隔为 1 秒if __name__ == “__main__”: main()
(三)使用代理服务器和用户代理
使用代理服务器可以隐藏爬虫的诚实 IP 地址,减少被服务器封禁的风险。同时,代理服务器可以分散请求,降低单个 IP 的请求频率。服务器可能会根据请求的用户代理(User-Agent)来判断请求是否来自爬虫。通过设置随机的用户代理,可以降低被服务器识别为爬虫的风险。
import requestsimport timefrom requests.adapters import HTTPAdapterfrom urllib3.util.retry import Retry 代理配置proxyHost = “www.16yun.cn”proxyPort = “5445”proxyUser = “16QMSOML”proxyPass = “280651” 用户代理池user_agents = [ “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3”, “Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36”, “Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Safari/605.1.15”, “Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:88.0) Gecko/20100101 Firefox/88.0”]def get_proxy(): “””获取认证代理””” return f”http://proxyUser}:proxyPass}@proxyHost}:proxyPort}”def create_session(): “””创建带有重试机制的会话””” session = requests.Session() retry_strategy = Retry( total=3, backoff_factor=1, status_forcelist=[500, 502, 503, 504] ) adapter = HTTPAdapter(max_retries=retry_strategy) session.mount(“http://”, adapter) session.mount(“https://”, adapter) return sessiondef fetch_url(url): “””获取URL内容””” session = create_session() proxy = get_proxy() headers = “User-Agent”: random.choice(user_agents)} try: response = session.get( url, proxies=”http”: proxy, “https”: proxy}, headers=headers, timeout=10 ) response.raise_for_status() print(f”成功获取: url} [情形码: response.status_code}]”) return response.text except requests.exceptions.HTTPError as e: if e.response.status_code == 503: print(f”503错误: url} – 服务器暂时不可用”) 可以在这里添加重试逻辑或记录到日志 else: print(f”HTTP错误 e.response.status_code}: url}”) raise except Exception as e: print(f”请求异常: url} – str(e)}”) raisedef main(): “””主函数””” urls = [ “http://example.com/page1”, “http://example.com/page2”, “http://example.com/page3″ ] for url in urls: try: fetch_url(url) time.sleep(1) 请求间隔 except Exception as e: print(f”处理 url} 时出错: e}”) continueif __name__ == “__main__”: import random 为user_agents随机选择 main()
(四)重试机制
当遇到 503 错误时,可以设置重试机制,等待一段时刻后再次尝试请求。这可以通过 <font style="color:rgba(0, 0, 0, 0.9);background-color:rgba(0, 0, 0, 0.03);">requests</font>
库的 <font style="color:rgba(0, 0, 0, 0.9);background-color:rgba(0, 0, 0, 0.03);">Session</font>
对象和 <font style="color:rgba(0, 0, 0, 0.9);background-color:rgba(0, 0, 0, 0.03);">Retry</font>
类来实现。
import requestsfrom requests.adapters import HTTPAdapterfrom requests.packages.urllib3.util.retry import Retrydef fetch_url(url): session = requests.Session() retries = Retry(total=5, backoff_factor=1, status_forcelist=[503]) session.mount(“http://”, HTTPAdapter(max_retries=retries)) try: response = session.get(url) response.raise_for_status() return response.text except requests.exceptions.HTTPError as e: if e.response.status_code == 503: print(f”503 error occurred for url}”) Handle 503 error else: raisedef main(): urls = [“http://example.com/page1”, “http://example.com/page2”, …] for url in urls: fetch_url(url)if __name__ == “__main__”: main()
三、综合操作案例
下面内容一个综合运用上述最佳操作的完整代码示例:
import concurrent.futuresimport requestsimport timeimport randomfrom requests.adapters import HTTPAdapterfrom requests.packages.urllib3.util.retry import Retryuser_agents = [ “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3”, “Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36”, 添加更多用户代理]proxies = [“http://proxy1.example.com:8080”, “http://proxy2.example.com:8080”, …]def fetch_url(url): headers = “User-Agent”: random.choice(user_agents)} session = requests.Session() retries = Retry(total=5, backoff_factor=1, status_forcelist=[503]) session.mount(“http://”, HTTPAdapter(max_retries=retries)) try: response = session.get(url, headers=headers, proxies=random.choice(proxies)) response.raise_for_status() return response.text except requests.exceptions.HTTPError as e: if e.response.status_code == 503: print(f”503 error occurred for url}”) Handle 503 error else: raisedef main(): urls = [“http://example.com/page1”, “http://example.com/page2″, …] max_workers = 10 控制并发线程数量 with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor: futures = [executor.submit(fetch_url, url) for url in urls] for future in concurrent.futures.as_completed(futures): try: data = future.result() Process data except Exception as e: print(f”Error: e}”) time.sleep(1) 设置请求间隔为 1 秒if __name__ == “__main__”: main()
四、拓展资料
在 Python 爬虫多线程并发时,503 错误一个常见的难题。通过合理控制并发线程数量、设置合理的请求间隔、使用代理服务器、添加重试机制和伪装用户代理等技巧,可以有效降低 503 错误的发生概率,进步爬虫的稳定性和可靠性。在实际开发中,开发者需要根据目标网站的具体情况,灵活运用这些最佳操作技巧,以确保爬虫的高效运行。
到此这篇关于Python多线程并发时出现503错误的最佳处理的文章就介绍到这了,更多相关Python处理503错误内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客!
无论兄弟们可能感兴趣的文章:
- Python并发多线程的具体操作步骤
- Python实现多线程并发请求测试的脚本
- 怎样使用Python多线程测试并发漏洞
- python多线程并发及测试框架案例
- Python并发:多线程与多进程的详解
- apache部署python程序出现503错误的解决技巧