Ошибка HTTP 403 в Python 3 Web Scraping

103

Я пытался отказаться от веб-сайта для практики, но продолжал получать ошибку 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
Джош
источник

Ответы:

221

Вероятно, это связано с 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()

У меня это работает.

Кстати, в вашем коде в строке отсутствует ()после , но я думаю, что это опечатка..readurlopen

СОВЕТ: так как это упражнение, выберите другой, неограничивающий сайт. Может они urllibпочему то блокируют ...

Стефано Санфилиппо
источник
Я предполагаю, что повторное использование reqдля нескольких urlopenвызовов безопасно.
Acumenus
Может быть, уже немного поздно, но у меня уже есть User-Agent в моем коде, он все равно дает мнеError 404: Access denied
Reema Parakh
Это работает, но я чувствую, что у них должна быть веская причина для блокировки ботов, а я
нарушаю
39

Определенно это блокируется из-за того, что вы используете 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')

Источник

Зета
источник
2
Главный ответ не сработал для меня, а ваш -. Большое спасибо!
Tarun Uday
Это работает нормально, но мне нужно прикрепить к нему конфигурацию ssl. Как мне это сделать? Раньше я просто добавил его как второй параметр (urlopen (request, context = ctx))
Hauke
2
выглядит , как это было открыто , но он говорит : «ValueError: чтение закрытого файла»
Martian2049
@zeta Как вам удалось очистить OfferUp и предоставить необходимые географические координаты для выполнения поиска из скрипта?
CJ Travis
@CJTravis, я не очищал OfferUp. Я просто получал значения элементов на основе точного URL-адреса элемента. Это не требует каких - либо координат гео для меня
дзета
14

"Вероятно, это из-за mod_security или какой-либо аналогичной функции безопасности сервера, которая блокирует известные

паук / бот

пользовательские агенты (urllib использует что-то вроде python urllib / 3.3.0, это легко обнаруживается) »- как уже упоминал Стефано Санфилиппо

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 . Поэтому вам нужно декодировать web_byte с помощью метода декодирования.

Это решает полную проблему, когда я пытался отказаться от веб-сайта с помощью PyCharm.

PS -> Я использую python 3.4

Роятирек
источник
3

Основываясь на предыдущем ответе,

from urllib.request import Request, urlopen       
#specify url
url = 'https://xyz/xyz'
req = Request(url, headers={'User-Agent': 'XYZ/3.0'})
response = urlopen(req, timeout=20).read()

Это сработало для меня, увеличив тайм-аут.

ВИКТОР ИВУОХА
источник
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

Попробуйте разместить заголовок User-Agent, который подделывает веб-клиент.

ПРИМЕЧАНИЕ . Страница содержит вызов Ajax, который создает таблицу, которую вы, вероятно, хотите проанализировать. Вам нужно будет проверить логику javascript страницы или просто использовать отладчик браузера (например, вкладку Firebug / Net), чтобы узнать, какой URL-адрес вам нужно вызвать, чтобы получить содержимое таблицы.

Роберт Луджо
источник
1

Вы можете попробовать двумя способами. Подробности по этой ссылке .

1) Через точку

pip install --upgrade certifi

2) Если это не сработает, попробуйте запустить команду Cerificates.com, которая поставляется в комплекте с Python 3. * для Mac: (перейдите в место установки python и дважды щелкните файл)

откройте / Applications / Python \ 3. * / Install \ Certificates.command

Джонсон
источник
1

Если вы чувствуете себя виноватым в том, что подделали пользовательский агент как Mozilla (комментарий в верхнем ответе от Стефано), он также может работать с пользовательским агентом без urllib. Это сработало для сайтов, на которые я ссылаюсь:

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

Мое приложение состоит в том, чтобы проверить достоверность, очищая определенные ссылки, на которые я ссылаюсь в своих статьях. Не обычный скребок.

Судип Прасад
источник
1

Основываясь на предыдущих ответах, это сработало для меня с Python 3.7.

from urllib.request import Request, urlopen

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

print(webpage)
Jonny_P
источник