Web 抓取 Python / 错误 506 无效请求

Cri*_*bio 5 python web-scraping python-3.x python-requests

我正在尝试抓取这个网站“https://www.ticketweb.com/search?q=”,但即使我可以在检查器中看到 HTML 元素并在通过 Python 请求时下载网页,我也只能得到那个错误。

这是我的脚本中的内容:

import requests

url_path = r'https://www.ticketweb.com/search?q='

HEADERS = {
    "Accept": "*/*",
    "Accept-Encoding": "utf-8",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"
}

response = requests.get(url_path, headers=HEADERS)

content = response.text

print(content)
Run Code Online (Sandbox Code Playgroud)

这是回应:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
  <head>
    <title>506 Invalid request</title>
  </head>
  <body>
    <h1>Error 506 Invalid request</h1>
    <p>Invalid request</p>
    <h3>Error 54113</h3>
    <p>Details: cache-dfw-kdfw8210093-DFW 1678372070 120734701</p>
    <hr>
    <p>Varnish cache server</p>
  </body>
</html>
Run Code Online (Sandbox Code Playgroud)

col*_*yre 3

看来请求标头正在受到严格审查。我对请求标头进行了一些操作,例如,在编写此答案时这是一个成功的请求:

import requests

url_path = r'https://www.ticketweb.com/search?q='

HEADERS = {
    "Accept-Language": "en-US,en",
    "Accept": "*/*;q=0.9",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"
}

response = requests.get(url_path, headers=HEADERS)
response.raise_for_status()
print(response.text)
Run Code Online (Sandbox Code Playgroud)

这里q有一个关于请求头中的 -Parameter 的很好的解释。太棒了;(据我了解)这表明该指令处理得不那么严格,您作为请求者接受了这一点。

我通过从 Firefox 请求复制完整的请求标头来找到解决方案,并尝试尽可能地最小化它,还使用了q已经提到的 -Parameter 。

编辑:同时此请求不再有效

重要的提示

如果您阅读页面上的使用条款,您将看到如下内容:

[...]您同意您不会:

  • 使用任何机器人、蜘蛛[...]
  • 使用任何自动化软件或计算机系统来搜索[...]

因此,网站所有者很可能会分析一些标准来查看请求是来自浏览器还是来自机器。如果他们假设计算机程序正在访问该站点,他们就可以阻止或操纵响应(例如,返回空结果或返回任意状态代码,如506甚至418 ,如果他们愿意的话)。

这意味着:网络抓取随时可能失败。特别是如果网站所有者不希望您自动下载他们的内容,因为网站运营商总是可以想出新的东西来阻止自动访问。

如果您被允许下载内容,您将需要做更多的工作,例如使用 selenium Web 驱动程序、考虑 cookie、人性化请求时间,并且可能并不总是使用相同的 IP 地址进行自动访问、使用站点的缓存等。

纯粹使用requests库或仅使用curl. 因此,与其伪造人工请求,为什么不使用浏览器并为您执行请求呢?

以下是如何通过 Selenium 浏览器请求的示例。这应该适用于 urlhttps://www.ticketweb.com/search?q=taylor+swiftdriver.find_element(by=By.TAG_NAME, value="body"). 浏览器还可以通过注入浏览器选项来无头使用--headless,因此在此过程中无需查看浏览器 UI。

但再次强调:网页抓取可能随时失败,如果您被允许自动阅读页面,请仔细阅读使用条款。

顺便说一句:此处utf-8未列为Accept-Encoding参数。但看来你无论如何都不需要它。