2017-01-04 1 views
1

Я пытаюсь загрузить некоторый контент, используя Python's urllib.request. Следующая команда дает исключение:Почему urllib.request.urlopen иногда не работает, но браузеры работают?

import urllib.request 
print(urllib.request.urlopen("https://fpgroup.foreignpolicy.com/foreign-policy-releases-mayjune-spy-issue/").code) 

результат:

... 
HTTPError: HTTP Error 403: Forbidden 

, если я использую FireFox или ссылки (командной строки браузера) Я получаю содержание и код состояния 200. Если я использую рысь, достаточно странно, я также получаю 403.

Я ожидаю, что все методы работы

  1. точно так же

Почему это не так?

+0

Может быть, сайт блокирует людей от выскабливание, проверяя данные заголовка и все эти вещи. Попробуйте настроить его? – MooingRawr

+0

@MooingRawr: вот и все ... пожалуйста, сделайте это ответом. – steffen

+0

также: кто они стараются держаться подальше? Даже такие люди, как я, которые не получают этого сами, знают, как пользоваться Интернетом ... – steffen

ответ

2

Скорее всего, сайт блокирует людей от соскабливания их сайтов. Вы можете обмануть их на базовом уровне, включив информацию заголовка вместе с другими материалами. См. Здесь для получения дополнительной информации.

Цитируя: https://docs.python.org/3/howto/urllib2.html#headers

import urllib.parse 
import urllib.request 

url = 'http://www.someserver.com/cgi-bin/register.cgi' 
user_agent = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64)' 
values = {'name' : 'Michael Foord', 
      'location' : 'Northampton', 
      'language' : 'Python' } 
headers = { 'User-Agent' : user_agent } 

data = urllib.parse.urlencode(values) 
data = data.encode('ascii') 
req = urllib.request.Request(url, data, headers) 
with urllib.request.urlopen(req) as response: 
    the_page = response.read() 

Есть много причин, почему люди не хотят скрипты, чтобы очистить свои веб-сайты. Для этого требуется пропускная способность. Они не хотят, чтобы люди получали выгоду (с точки зрения денег), создавая борода. Возможно, они не хотят, чтобы вы копировали информацию о своем сайте. Вы можете также думать об этом как о книге. Авторы хотят, чтобы люди читали свои книги, но, возможно, некоторые из них не захотят, чтобы робот сканировал свои книги, чтобы создать копию, или, может быть, робот мог бы ее обобщить.

Вторая часть вашего вопроса в комментарии является неопределенной и широкой, чтобы ответить здесь, поскольку есть слишком много упрямых ответов.

+0

относительно второго вопроса («кто они пытаются удержаться»): это был скорее ретрительный вопрос ;) – steffen

2

Я пробовал с этим кодом, и все было в порядке.

Я просто добавил headers к запросу. Смотрите пример ниже:

from urllib.request import Request, urlopen, HTTPError 
from time import sleep 

def get_url_data(url = ""): 
    try: 
     request = Request(url, headers = {'User-Agent' :\ 
      "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.36"}) 

     response = urlopen(request) 
     data = response.read().decode("utf8") 
     return data 
    except HTTPError: 
     return None 

url = "https://fpgroup.foreignpolicy.com/foreign-policy-releases-mayjune-spy-issue/" 

for i in range(50): 
    d = get_url_data(url) 
    if d != None: 
     print("Attempt %d was a Success" % i) 
    else: 
     print("Attempt %d was a Failure" % i) 
    sleep(1) 

Выход:

Attempt 0 was a Success 
Attempt 1 was a Success 
Attempt 2 was a Success 
Attempt 3 was a Success 
Attempt 4 was a Success 
Attempt 5 was a Success 
Attempt 6 was a Success 
Attempt 7 was a Success 
Attempt 8 was a Success 
Attempt 9 was a Success 
... 
Attempt 42 was a Success 
Attempt 43 was a Success 
Attempt 44 was a Success 
Attempt 45 was a Success 
Attempt 46 was a Success 
Attempt 47 was a Success 
Attempt 48 was a Success 
Attempt 49 was a Success 
+2

Пожалуйста, не наводняйте веб-сайты путем повторных запросов. По крайней мере, используйте 'time.sleep' между ними. – bfontaine

+0

Хорошо, я добавлю 'time.sleep' между каждым запросом. Спасибо за ваш комментарий. –

+0

@ bfontaine: Я не буду. Сначала я проверяю rss-канал для новых элементов и загружаю только новые статьи определенной темы. Проблема возникла, когда я впервые запустил скрипт и попросил несколько статей случайно. – steffen

Смежные вопросы