使用Python Requests爬取Etherscan遇Cloudflare拦截及SSL错误求助
问题根源
你的代码存在两个致命错误,直接触发了SSL握手失败:
- Host头配置错误:你把Host设为了
grimaldis.myguestaccount.com,这不是Etherscan的域名,服务器无法识别请求,直接拒绝SSL握手。 - 直接访问IP地址:HTTPS请求依赖SNI(服务器名称指示)匹配对应域名的SSL证书,直接用IP访问会让服务器无法返回正确证书,引发握手失败。
另外,原始的Cloudflare人机验证问题,requests库本身无法绕过——Cloudflare会检测请求是否来自真实浏览器环境,无浏览器的纯HTTP请求会被拦截。
错误信息(中文翻译)
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/connectionpool.py", line 677, in urlopen
chunked=chunked,
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/connectionpool.py", line 381, in _make_request
self._validate_conn(conn)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/connectionpool.py", line 976, in validate_conn
conn.connect()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/connection.py", line 370, in connect
ssl_context=context,
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/util/ssl.py", line 390, in ssl_wrap_socket
return context.wrap_socket(sock)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py", line 407, in wrap_socket
_context=self, _session=session)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py", line 814, in init
self.do_handshake()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py", line 1068, in do_handshake
self._sslobj.do_handshake()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py", line 689, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3握手失败警报 (_ssl.c:833)在处理上述异常期间,发生了另一个异常:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/requests/adapters.py", line 449, in send
timeout=timeout
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/connectionpool.py", line 725, in urlopen
method, url, error=e, _pool=self, _stacktrace=sys.exc_info()[2]
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/util/retry.py", line 439, in increment
raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='172.67.8.107', port=443): 超过最大重试次数,URL: /tokens (由SSLError引起(SSLError(1, '[SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3握手失败警报 (_ssl.c:833)'),))在处理上述异常期间,发生了另一个异常:
Traceback (most recent call last):
File "label_scrapper.py", line 16, in
response = s.get(f"https://{address}/tokens", headers=headers, verify=False).text
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/requests/sessions.py", line 543, in get
return self.request('GET', url, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/requests/sessions.py", line 530, in request
resp = self.send(prep, **send_kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/requests/sessions.py", line 643, in send
r = adapter.send(request, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/requests/adapters.py", line 514, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='172.67.8.107', port=443): 超过最大重试次数,URL: /tokens (由SSLError引起(SSLError(1, '[SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3握手失败警报 (_ssl.c:833)'),))
修复方案
1. 修正基础请求错误
先解决代码中的格式错误,确保请求符合HTTP规范(但这一步仍无法绕过Cloudflare验证):
import requests from collections import OrderedDict from requests import Session s = Session() headers = OrderedDict({ 'Accept-Encoding': 'gzip, deflate, br', 'Host': "etherscan.io", 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:77.0) Gecko/20100101 Firefox/77.0' }) s.headers = headers # 直接用域名访问,不要解析IP response = s.get("https://etherscan.io/tokens", headers=headers) print(response.text)
2. 绕过Cloudflare验证的有效方法
方法一:使用cloudscraper库
cloudscraper是专门绕过Cloudflare反爬的工具,会模拟浏览器JS环境处理验证:
- 安装:
pip install cloudscraper - 代码示例:
import cloudscraper scraper = cloudscraper.create_scraper() response = scraper.get("https://etherscan.io/tokens") print(response.text)
方法二:用Selenium模拟真实浏览器
通过模拟浏览器行为,完全绕过Cloudflare人机检测:
- 安装:
pip install selenium,并下载对应浏览器驱动(如ChromeDriver) - 代码示例:
from selenium import webdriver from selenium.webdriver.chrome.options import Options options = Options() options.add_argument("--headless=new") # 无头模式,不显示浏览器窗口 options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:77.0) Gecko/20100101 Firefox/77.0") driver = webdriver.Chrome(options=options) driver.get("https://etherscan.io/tokens") print(driver.page_source) driver.quit()
重要提醒
- 优先使用官方API:Etherscan提供了稳定的官方API接口,比爬取网页更合规,建议优先使用。
- 遵守爬虫礼仪:添加适当延时(如
time.sleep(2)),避免频繁请求导致IP被封禁。 - 检查服务条款:爬取前请阅读Etherscan的服务协议和
robots.txt,确保行为合规。
内容的提问来源于stack exchange,提问作者Somdip Dey

