网页抓取:页面存在,但使用 requests/urllib 获取 404

May*_*tal 3 web-scraping python-3.x

我正在尝试抓取以下页面: http://usbcdirectory.com/listing/1-us-black-chambers

我正在使用Python 3.5.0

这是我的代码:

urllib.request.urlopen('http://usbcdirectory.com/listing/1-us-black-chambers')
Run Code Online (Sandbox Code Playgroud)

使用上面的内容我收到 404 未找到错误。但是,当我从浏览器打开该页面时,该页面存在。

我尝试寻找这个问题的解决方案,这是我发现的:

  1. 将 urllib 更改为 requests:我已经这样做了,并且状态代码中出现 404 错误
>>>requests.get('http://usbcdirectory.com/listing/1-us-black-chambers')
    
Request <404>
Run Code Online (Sandbox Code Playgroud)
  1. 我检查了我的链接是正确的

  2. 我试图查明该页面是否是使用 JavaScript 生成的。我相信事实并非如此。

这里的网页有什么问题吗?他们是否以某种方式阻止抓取,或者是 URL 的问题?

rit*_*iek 6

正如您所猜测的,他们可能会阻止您的请求。您可以传递自定义标头来模拟您的请求,就像来自真实浏览器的请求一样:

import requests

url = 'http://usbcdirectory.com/listing/1-us-black-chambers'
headers = {'Accept': 'text/html'}
response = requests.get(url, headers=headers)
print(response.status_code)
Run Code Online (Sandbox Code Playgroud)

  • @Ritiek,您提供的解决方案有效。这是一个很好的发现。为此+1。顺便说一句,你能告诉我为什么它不起作用 `headers={'User-Agent':'Mozilla/5.0'}` 吗?通常,这就是我们在传递这样的标头时模拟浏览器的做法。然而,它没有成功,但你的成功了。 (3认同)
  • @Topto 这通常取决于网站他们想要阻止哪种网络请求。您可以使用 [mitmproxy](https://github.com/mitmproxy/mitmproxy) 拦截浏览器传递的所有标头并将它们复制到您的代码中,直到它正常工作。 (2认同)