148

我试图抓取一个网站进行练习,但我不断收到 HTTP 错误 403(它认为我是机器人)吗?

这是我的代码:

#import requests
import urllib.request
from bs4 import BeautifulSoup
#from urllib import urlopen
import re

webpage = urllib.request.urlopen('http://www.cmegroup.com/trading/products/#sortField=oi&sortAsc=false&venues=3&page=1&cleared=1&group=1').read
findrows = re.compile('<tr class="- banding(?:On|Off)>(.*?)</tr>')
findlink = re.compile('<a href =">(.*)</a>')

row_array = re.findall(findrows, webpage)
links = re.finall(findlink, webpate)

print(len(row_array))

iterator = []

我得到的错误是:

 File "C:\Python33\lib\urllib\request.py", line 160, in urlopen
    return opener.open(url, data, timeout)
  File "C:\Python33\lib\urllib\request.py", line 479, in open
    response = meth(req, response)
  File "C:\Python33\lib\urllib\request.py", line 591, in http_response
    'http', request, response, code, msg, hdrs)
  File "C:\Python33\lib\urllib\request.py", line 517, in error
    return self._call_chain(*args)
  File "C:\Python33\lib\urllib\request.py", line 451, in _call_chain
    result = func(*args)
  File "C:\Python33\lib\urllib\request.py", line 599, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 403: Forbidden
4

7 回答 7

296

这可能是因为mod_security或某些类似的服务器安全功能阻止了已知的蜘蛛/机器人用户代理(urllib使用类似的东西python urllib/3.3.0,很容易检测到)。尝试设置一个已知的浏览器用户代理:

from urllib.request import Request, urlopen

req = Request('http://www.cmegroup.com/trading/products/#sortField=oi&sortAsc=false&venues=3&page=1&cleared=1&group=1', headers={'User-Agent': 'Mozilla/5.0'})
webpage = urlopen(req).read()

这对我有用。

顺便说一句,在您的代码中,您缺少该行中的()after ,但我认为这是一个错字。.readurlopen

提示:由于这是练习,请选择一个不同的、非限制性的站点。也许他们urllib出于某种原因阻止了......

于 2013-05-18T17:52:11.737 回答
51

绝对是因为您使用基于用户代理的 urllib 而导致阻塞。OfferUp 也发生了同样的事情。您可以创建一个名为 AppURLopener 的新类,它使用 Mozilla 覆盖用户代理。

import urllib.request

class AppURLopener(urllib.request.FancyURLopener):
    version = "Mozilla/5.0"

opener = AppURLopener()
response = opener.open('http://httpbin.org/user-agent')

资源

于 2015-08-01T06:00:29.413 回答
25

“这可能是因为mod_security或某些类似的服务器安全功能阻止了已知

蜘蛛/机器人

用户代理(urllib 使用类似 python urllib/3.3.0 的东西,它很容易被检测到)”——正如 Stefano Sanfilippo 已经提到的

from urllib.request import Request, urlopen
url="https://stackoverflow.com/search?q=html+error+403"
req = Request(url, headers={'User-Agent': 'Mozilla/5.0'})

web_byte = urlopen(req).read()

webpage = web_byte.decode('utf-8')

web_byte是服务器返回的字节对象,网页中存在的内容类型主要是utf -8。因此,您需要使用 decode 方法对web_byte进行解码。

这解决了我在尝试使用PyCharm从网站上抓取数据时的完整问题

PS->我使用python 3.4

于 2017-12-25T07:57:59.673 回答
6

根据之前的答案,这对我使用 Python 3.7 有效,方法是将超时时间增加到 10。

from urllib.request import Request, urlopen

req = Request('Url_Link', headers={'User-Agent': 'XYZ/3.0'})
webpage = urlopen(req, timeout=10).read()

print(webpage)
于 2020-04-16T18:48:32.550 回答
2

由于页面在浏览器中工作,而不是在 python 程序中调用时,似乎提供该url的网络应用程序识别出您不是通过浏览器请求内容。

示范:

curl --dump-header r.txt http://www.cmegroup.com/trading/products/#sortField=oi&sortAsc=false&venues=3&page=1&cleared=1&group=1

...
<HTML><HEAD>
<TITLE>Access Denied</TITLE>
</HEAD><BODY>
<H1>Access Denied</H1>
You don't have permission to access ...
</HTML>

并且 r.txt 中的内容有状态行:

HTTP/1.1 403 Forbidden

尝试发布伪造Web 客户端的标题“User-Agent”。

注意:该页面包含创建您可能要解析的表的 Ajax 调用。您需要检查页面的 javascript 逻辑或简单地使用浏览器调试器(如 Firebug / Net 选项卡)来查看需要调用哪个 url 来获取表的内容。

于 2013-05-18T17:55:26.873 回答
1

你可以尝试两种方式。详细信息在此链接中。

1)通过点子

pip install --upgrade 证书

2)如果它不起作用,请尝试运行与 Python 3.* for Mac 捆绑在一起的Cerificates.command :(转到您的 python 安装位置并双击该文件)

打开 /Applications/Python\ 3.*/Install\ Certificates.command

于 2018-11-16T03:55:40.390 回答
1

如果您对将用户代理伪装成 Mozilla 感到内疚(在 Stefano 的最佳答案中评论),它也可以与非 urllib 用户代理一起使用。这适用于我参考的网站:

    req = urlrequest.Request(link, headers={'User-Agent': 'XYZ/3.0'})
    urlrequest.urlopen(req, timeout=10).read()

我的应用程序是通过抓取我在文章中引用的特定链接来测试有效性。不是通用刮刀。

于 2020-03-14T03:22:10.903 回答