【问题标题】:Scraping with Python getting blocked only on AWS instances -get requests blocked仅在 AWS 实例上阻止使用 Python 进行抓取 - 阻止请求
【发布时间】:2020-10-10 13:29:57
【问题描述】:

我已经构建了一个脚本来抓取 www.tesco.com 杂货结果页面,示例链接:

https://www.tesco.com/groceries/en-GB/search?query=kitkat

不幸的是,我的 Python 脚本被服务器阻止(常规获取请求)。我什至尝试在我的机器上使用 CURL 进行故障排除:

curl htpps://www.tesco.com

但我得到以下回复:

<HTML><HEAD>
<TITLE>Access Denied</TITLE>
</HEAD><BODY>
<H1>Access Denied</H1>
 
You don't have permission to access "http&#58;&#47;&#47;dce&#45;homepage&#46;tesco&#46;com&#47;" on this server.<P>
Reference&#32;&#35;18&#46;496cd417&#46;1592645071&#46;44e961c
</BODY>
</HTML>

当尝试使用带有标准标题的 Postman 时,我得到 200 OK 响应。 在我的脚本中,我尝试使用与 Postman 相同的标题并且我得到 200 OK,但前提是我在本地 PC 上使用它。当我在 AWS 上启动一个新的实例时——Ubuntu 18.04 或类似的免费层——CURL 得到 404 如上所述。理想情况下,我希望我的脚本可以在 AWS 上运行。运行时,脚本不起作用 - 只是挂起。 当我打断它时,我得到以下信息:

^CTraceback (most recent call last):
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 380, in _make_request
    httplib_response = conn.getresponse(buffering=True)
TypeError: getresponse() got an unexpected keyword argument 'buffering'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "ttest.py", line 18, in <module>
    results = requests.get(url, headers = headers)
  File "/usr/lib/python3/dist-packages/requests/api.py", line 72, in get
    return request('get', url, params=params, **kwargs)
  File "/usr/lib/python3/dist-packages/requests/api.py", line 58, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 520, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 630, in send
    r = adapter.send(request, **kwargs)
  File "/usr/lib/python3/dist-packages/requests/adapters.py", line 440, in send
    timeout=timeout
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 601, in urlopen
    chunked=chunked)
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 383, in _make_request
    httplib_response = conn.getresponse()
  File "/usr/lib/python3.6/http/client.py", line 1356, in getresponse
    response.begin()
  File "/usr/lib/python3.6/http/client.py", line 307, in begin
    version, status, reason = self._read_status()
  File "/usr/lib/python3.6/http/client.py", line 268, in _read_status
    line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
  File "/usr/lib/python3.6/socket.py", line 586, in readinto
    return self._sock.recv_into(b)
  File "/usr/lib/python3.6/ssl.py", line 1012, in recv_into
    return self.read(nbytes, buffer)
  File "/usr/lib/python3.6/ssl.py", line 874, in read
    return self._sslobj.read(len, buffer)
  File "/usr/lib/python3.6/ssl.py", line 631, in read
    v = self._sslobj.read(len, buffer)
KeyboardInterrupt

也许 tesco.com 已经禁止所有 AWS 实例抓取他们的网站?

这是在我的 PC 上运行但不在 AWS 实例上运行的代码。

'EDIT' - 我已经尝试在标题中使用我们的 cookie - 仍然没有运气。


import requests
headers = {'User-Agent': 'PostmanRuntime/7.25.0',
'Accept': '*/*',
'Cache-Control': 'no-cache',
'Host': 'www.tesco.com',
'Accept-Encoding': 'gzip, deflate, br',
'Connection': 'keep-alive',
'Cookie': 'bm_sz=04919BE521C5C4D8ADF4617D5250A484~YAAQrpxkX+b8IYVyAQAA/VQr0QgTg5gDEXUmuUfa0qqtHv0QHHZjtL4gcSJ9RA7hoaEXJOTp1DYPb9xCrGwP37BrvtUY2kCKB7PqvVLXAXnfrt9F0ZiEPj10SiSVXZRZj8klW46ZA7Ho/0XtWlsO2aFX1MPkmD2/C10cDH6E1PgeO9EUNkZi9uPu109p4DE=; _abck=5621BD87FE69A39458BD0AB267BB9A81~-1~YAAQrpxkX+f8IYVyAQAA/VQr0QTSvxcBlxnRsND9THtPksH0EbfK/A3XkW0xT9oCk0Bj1ewbVDXr3PqtBjR7hHO6h6IXMvC2XID5RrAk0gVEKGwm9RDyBWyvp6hnPzicHMH6tTUIZdYLmssjIBAJ2WnpBkKUuF0YbX45V4H8d3m6u8FOhyqZewFyT1+Yvh14NDHwmDw4Yb4hQkLPglrkzt8LV39SpfSjjGkWMjyX4l967aCe+SHK5hjcTIz9bjSAoOQNqFWR5ATMnfBDSLOfaAQ4Dic=~-1~-1~-1; atrc=48693e75-78d9-4fce-85d0-9a0a50232644; _csrf=2wH2UKiamS-tjvd4hERekcG2',
'Referer': 'http://www.tesco.com/'

}

url = 'https://www.tesco.com/groceries/en-GB/search?query=kitkat'
results = requests.get(url, headers = headers)

print(results.status_code)

www.tesco.comrobots.txt不禁止抓取:


Sitemap: https://www.tesco.com/UK.sitemap.xml
 
User-agent: *
Disallow: *reviews/submission/*
Disallow: *&sortBy*
Disallow: *promotion=*
Disallow: *currentModal*
Disallow: *active-tab*
Disallow: *include-children*
Disallow: *new&new*
Disallow: /groceries/*reviews/submission

编辑

我已将 headless chrome webbrowser 下载到我在 AWS 上的 ubuntu 服务器实例,并尝试截取 tesco.com 的屏幕截图。我收到以下错误:

为了澄清,我尝试浏览 https 地址 - 这不重要,因为我确定它有 https 重定向。

【问题讨论】:

  • 我对 CSRF 令牌有怀疑,但我能够在 repl.it 窗口和 Digital Ocean 实例上都得到一个 200 响应,其中包含您的代码。我的另一个怀疑是关于速率限制。尝试实施指数退避?
  • 好吧,我不会以高速率向 tesco.com 发送请求。目前我每天运行几次脚本。我将尝试在 AWS 安装 Postman 上启动一个 Windows 实例并重试 - 这可能会告诉我是否所有 AWS IP 都被 tesco.co 阻止了,或者可能只有 Linux 实例?
  • @shaunakde 版本不匹配是什么意思?我目前正在使用 Python 3.8.2
  • 我可以在本地机器上运行 curl 'https://www.tesco.com/groceries/en-GB/search?query=kitkat' -H 'User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:77.0) Gecko/20100101 Firefox/77.0' 并且它可以工作,但从 AWS 实例运行它不起作用。我猜 AWS IP 被阻止了,我也希望常见代理被阻止,并且一些用户代理似乎也被阻止,例如卷曲。
  • @Dan-Dev 谢谢!我希望其他人会启动 AWS 实例并进行检查。现在我确定不只是我 :) 我将研究一些付费代理。有谁知道便宜的吗?我的项目不是商业项目,所以我不想在 Portfolio 应用上花很多钱。

标签: python web-scraping python-requests postman


【解决方案1】:

看起来 Tesco.com 正在阻止 AWS IP 地址。我已经使用付费代理,现在可以正常工作。感谢@Dan-Dev 帮助检查您的 AWS 实例。

【讨论】:

    【解决方案2】:

    AWS 以 json 格式发布他们的 IP ranges。这可以导入到 Web 服务器中,以停止网站抓取。我希望像 Tescos 这样的大型超市连锁店能够实现这一点。

    要尝试的一件事是将 AWS 区域更改为最新的区域,例如 Europe (Paris) eu-west-3。他们的 IP 范围过时的可能性很小。

    还有一个可能是,拥有 AWS lamada 且共享 IP 范围相同的人在短时间内提交了许多请求并被自动阻止。

    要解决此问题,您可以连接到 VPN,这将隐藏您的 AWS IP 地址。您也可以在本地计算机上创建一个VPC(因此使用您的本地 PC IP 地址)。

    【讨论】:

    • 谢谢!我只是在检查 AWS Windows 服务器实例是否会被阻止。我确实尝试使用代理进行抓取 - 是的,免费的,不幸的是我仍然被阻止。我想我可以试试 VPN。
    • 仅出于测试目的,您可以创建一个基本的 python lambda 并尝试各种区域。它也不应该有所作为,但在您的标题中,您应该只需要裁判和用户代理(并将用户代理设置为 Chrome)。设置主机有时会导致问题。
    • 好的,我刚刚在 AWS 的 Windows 实例上尝试了 curl www.tesco.com - 没有回复。但是使用 IE 可以让我浏览他们的网站。嗯,有什么想法吗?
    • 我使用了额外的标头选项来模拟 Postman 请求,因为这些请求正常。
    • 我刚刚在我的 linux 实例上尝试了 wget - 同样的问题:wget https://www.tesco.com--2020-06-20 13:49:56-- https://www.tesco.com/ Resolving www.tesco.com (www.tesco.com)... 23.218.140.69 Connecting to www.tesco.com (www.tesco.com)|23.218.140.69|:443... connected. HTTP request sent, awaiting response...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-04
    • 1970-01-01
    • 1970-01-01
    • 2021-01-05
    • 1970-01-01
    • 1970-01-01
    • 2019-01-27
    相关资源
    最近更新 更多