如何修复请求库中"Max retries exceeded with url"错误?



我编写了一个运行在AWS Lambdas上的网络爬虫。每60分钟一班。它工作了一年,但最近我开始得到这样的错误:

HTTPSConnectionPool(host='www.niederglatt-zh.ch', port=443): Max retries exceeded with url: /amtlichepublikationen (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x7f449f63a2d0>: Failed to establish a new connection: [Errno 111] Connection refused')) 

这是我要抓取的链接:

https://www.niederglatt-zh.ch/amtlichepublikationen

这是我的代码:

def sending_request(input_url):
try:
response = requests.get(input_url, allow_redirects=True, headers=get_random_header())
print("Connection Response:", response, "Status Code:", response.status_code)
if response.status_code != 200:
time.sleep(random.randint(3, 7))
response = requests.get(input_url, allow_redirects=True, headers=get_random_header(), verify = False, timeout=15)
print("Connection Response - Second Try:", response)
except:
time.sleep(random.randint(4, 7))
response = requests.get(input_url, allow_redirects=True, headers=get_random_header(), verify = False, timeout=15)
print("Connection Response (verify == False):", response)    

return response

我已经试着"播放"了。用allow_redirects = True/False,用timeoutverify==True/False但是我总是得到相同的错误。

可以忽略headers=get_random_header()

get_random_header()是一个从用户代理列表中随机给出用户代理的函数。

我也有脚本爬行活动代理:

# LIST OF FREE PROXY APIs, THESE PROXIES ARE LAST TIME TESTED 60 MINUTES AGO, PROTOCOLS: HTTP, HTTPS, SOCKS4 AND SOCKS5
proxy_url = "https://proxylist.geonode.com/api/proxy-list?limit=200&page=1&sort_by=lastChecked&sort_type=desc&speed=fast"
# EXTRACTING JSON DATA FROM THIS LIST OF PROXIES
# Sending request to API
proxy_json = requests.get(proxy_url, headers=get_random_header()).text
proxy_json = json.loads(proxy_json)
full_proxy_list = proxy_json["data"]
# CREATING PROXY DICT
final_proxy_list = []
for proxy in full_proxy_list:
#print(proxy) # JSON VALUE FOR ALL DATA THAT GOES INTO PROXY
# Extracting protocol, ip address and port
protocol = proxy['protocols'][0]
if protocol != "https":
ip_ = proxy['ip']
port = proxy['port']
# Creating PROXY dict
proxy = {protocol : protocol + '://' + ip_ + ':' + port}
final_proxy_list.append(proxy)

我已经尝试像这样将随机代理传递给代码:

response = requests.get(input_url, allow_redirects=True, headers=get_random_header(), proxies = random.choice(final_proxy_list))

但是我仍然得到相同的错误。

有办法修复这个错误吗?我应该在Python代码中添加一些东西,还是应该在lambdas中更改一些东西?

谢谢:)

看起来您的请求被某些东西阻止了。唯一的问题是,这是你自己造成的,还是AWS阻止的?大多数时候,你自己会犯错误,每个人都会犯错。尝试以下所有方法来查找原因:

  • 第一个简单的命令行测试:curl -I https://www.niederglatt-zh.ch/amtlichepublikationen。状态应该是200。
  • 第二,我不认为这是一个速率限制问题,因为你可能会得到一个状态码429
  • 将您的网站替换为https://google.com,例如,响应应该成功。
  • 添加一些额外的随机字符到您的域名,然后再试一次,你应该得到类似"无法解析主机"的东西;错误。
  • 向https://ifconfig.me请求,响应应该成功,使用lambda的出站IP地址。
  • 如果上述任何一项失败,我会查看网络配置的方向(如果存在)。下面是如何配置lambda和vpc的详细指南。
  • 您最近是否更改了您的Lambda的网络配置?
  • 尝试在本地运行代码,我假设您已经这样做了。我自己试过了,成功了。
  • 作为最后的手段,重新部署一个新的干净的Lambda(到另一个区域)。只有当所有其他步骤都没有成功时,因为您可能无法从中获得确切的根本原因。

另外,看看你的代码,我建议使用请求包内的重试机制。这使得代码在需要调试时更容易理解。请看下面的例子:

from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
retry_strategy = Retry(
total=3,
backoff_factor=1
)
adapter = HTTPAdapter(max_retries=retry_strategy)
http = requests.Session()
http.mount("https://", adapter)
http.mount("http://", adapter)
response = http.get("https://www.niederglatt-zh.ch/amtlichepublikationen")

如上所述,目标网络可能已经阻止了您所在地区的公共ip地址。lambda函数将具有动态内部ip地址,但这些地址不是目标网络所看到的。你可以在不同的地区设置你的EXACT应用程序,看看是否能解决你的问题。

另外,您可能需要遵循本文中提到的一些最佳实践:

https://www.blog.datahut.co/post/web-scraping-best-practices-tips以下是一些:

  1. 温柔
  2. 尊重robots . txt

这很可能是由于提供商阻止了抓取尝试。通常情况下,他们可能会查看他们的日志,并注意到试图抓取机器人并阻止你的IP。或者他们可能配置了某种形式的防火墙。看看主机的条款和条件,看看是否有任何关于爬行或网站的机器人。你可以尝试的一件事是转移到另一个地区,尝试爬行,如果成功,那就是IP阻塞。希望对你有所帮助

相关内容

最新更新