Ошибка 501 ScraPy — код состояния HTTP не обрабатывается или не разрешен

Получил ошибку выше. Пробежался по SO и только об 403 или 404 ошибках заговорил.

Вот некоторые вещи, которые я пытался заставить это работать.

  • отредактировал user_agent в мою строку
  • проверил robots.txt Reddit, но не запретил параметры сканирования
  • пытался настроить URL и домены (не сработало)
  • сделал scrapy shell .. та же ошибка, но без объяснения причин
  • сайт работает в моем браузере на ноутбуке
  • проверил http 501, относится к "не реализовано" или сервер не поддерживает функциональность

И поля ошибок

2019-04-07 17:34:00 [scrapy.middleware] INFO: Enabled item pipelines:
[]
2019-04-07 17:34:00 [scrapy.core.engine] INFO: Spider opened
2019-04-07 17:34:00 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2019-04-07 17:34:00 [scrapy.extensions.telnet] INFO: Telnet console listening on 127.0.0.1:6023
2019-04-07 17:34:00 [scrapy.downloadermiddlewares.redirect] DEBUG: Redirecting (301) to <GET https://www.reddit.com/robots.txt> from <GET http://www.reddit.com/robots.txt>
2019-04-07 17:34:00 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://www.reddit.com/robots.txt> (referer: None)
2019-04-07 17:34:00 [scrapy.downloadermiddlewares.redirect] DEBUG: Redirecting (301) to <GET https://www.reddit.com/r/gameofthrones//> from <GET http://www.reddit.com/r/gameofthrones//>
2019-04-07 17:34:01 [scrapy.core.engine] DEBUG: Crawled (501) <GET https://www.reddit.com/r/gameofthrones//> (referer: None)
2019-04-07 17:34:01 [scrapy.spidermiddlewares.httperror] INFO: Ignoring response **<501 https://www.reddit.com/r/gameofthrones//>: HTTP status code is not handled or not allowed**
2019-04-07 17:34:01 [scrapy.core.engine] INFO: Closing spider (finished)

Коды

class RedditbotSpider(scrapy.Spider):

    name = "redditgetter"
    allowed_domains = ['reddit.com']
    start_urls = ['http://www.reddit.com/r/gameofthrones/']
    custom_settings = {
       'FEED_URI' : 'tmp/redditdata.csv'
    }

    def parse(self, response):

        titles = response.css('.title.may-blank::text').extract()
        votes = response.css('.score.unvoted::text').extract()
        times = response.css('time::attr(title)').extract()

        for item in zip(titles,votes,times):

            scraped_info = {
                'title' : item[0],
                'vote' : item[1],
                'created_at' : item[2],
            }

            yield scraped_info

ОБНОВЛЕНИЕ: исправлена ​​новая ошибка после отступа и "//".

2019-04-07 23:00:44 [scrapy.core.engine] INFO: Spider opened
2019-04-07 23:00:44 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2019-04-07 23:00:44 [scrapy.extensions.telnet] INFO: Telnet console listening on 127.0.0.1:6023
2019-04-07 23:00:44 [scrapy.downloadermiddlewares.redirect] DEBUG: Redirecting (301) to <GET https://www.reddit.com/robots.txt> from <GET http://www.reddit.com/robots.txt>
2019-04-07 23:00:45 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://www.reddit.com/robots.txt> (referer: None)
2019-04-07 23:00:45 [scrapy.downloadermiddlewares.redirect] DEBUG: Redirecting (301) to <GET https://www.reddit.com/r/gameofthrones/> from <GET http://www.reddit.com/r/gameofthrones/>
2019-04-07 23:00:47 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://www.reddit.com/r/gameofthrones/> (referer: None)
2019-04-07 23:00:47 [scrapy.core.engine] INFO: Closing spider (finished)
2019-04-07 23:00:47 [scrapy.statscollectors] INFO: Dumping Scrapy stats:
{'downloader/request_bytes': 1287,
 'downloader/request_count': 4,
 'downloader/request_method_count/GET': 4,
 'downloader/response_bytes': 101351,
 'downloader/response_count': 4,
 'downloader/response_status_count/200': 2,
 'downloader/response_status_count/301': 2,
 'finish_reason': 'finished',
 'finish_time': datetime.datetime(2019, 4, 7, 15, 0, 47, 452284),
 'log_count/DEBUG': 4,
 'log_count/INFO': 9,
 'memusage/max': 50294784,
 'memusage/startup': 50290688,
 'response_received_count': 2,
 'robotstxt/request_count': 1,
 'robotstxt/response_count': 1,
 'robotstxt/response_status_count/200': 1,
 'scheduler/dequeued': 2,
 'scheduler/dequeued/memory': 2,
 'scheduler/enqueued': 2,
 'scheduler/enqueued/memory': 2,
 'start_time': datetime.datetime(2019, 4, 7, 15, 0, 44, 502445)}
2019-04-07 23:00:47 [scrapy.core.engine] INFO: Spider closed (finished)
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
494
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Эта проблема не имеет ничего общего с реализацией вашего кода, это просто опечатка в URL-адресе. Мне удалось воспроизвести проблему (код состояния 501), отправив запрос GET на https://www.reddit.com/r/gameofthrones// через https://reqbin.com/u4xxuehu.

Вам просто нужно удалить лишнюю косую черту в конце URL-адреса, чтобы получить статус 200 (OK): https://reqbin.com/43le52w4


Изменить, касающееся очистки Reddit: в вашем коде нет ошибки, он успешно получает ответ размером 101351 байт (вы можете проверить это самостоятельно, напечатав response.body в методе parse()): 'downloader/response_bytes': 101351.

Проблема в том, как вы анализируете ответ. Вы используете селекторы CSS (например, response.css('.title.may-blank::text')), которые ничего не возвращают, потому что в HTML нет элементов с такими классами (проверьте источник веб-страницы в браузере и найдите элементы, которые вы пытаетесь выбирать). На самом деле вы заметите, что Reddit принимает меры против сканирования, назначая неизвестные классы элементам HTML.

Однако при проверке исходного кода оказывается, что конец страницы содержит данные JSON, завернутые в <script id = "data"></script>, которые включают информацию о сообщениях (заголовок, голоса и т. д.). Информация, которую вы хотите извлечь, структурирована следующим образом:

posts
└── models
    └── postId
        ├── title
        ├── score
        └── created

Вы можете просто загрузить и проанализировать данные JSON, чтобы получить нужные поля. Вот рабочая реализация метода parse():

def parse(self, response):

    # get the contents inside <script id = "data"></script>
    data = response.css('#data::text').get()
    # remove anything before { and after } to get valid JSON
    data = re.findall(r"{.*}",str(data), re.MULTILINE)[0];
    jsonresponse = json.loads(data)

    titles = []
    votes = []
    times = []
    for post in jsonresponse["posts"]["models"]:
        titles.append(jsonresponse["posts"]["models"][post]["title"])
        votes.append(jsonresponse["posts"]["models"][post]["score"])
        times.append(jsonresponse["posts"]["models"][post]["created"])

    for item in zip(titles,votes,times):
        scraped_info = {
                'title' : item[0],
                'vote' : item[1],
                'created_at' : item[2],
        }
        yield scraped_info

Пример вывода:

[scrapy.core.scraper] DEBUG: Scraped from <200 https://www.reddit.com/r/gameofthrones/>
{'title': '[NO SPOILERS] GoT this viewing party invite today. What do you think?', 'vote': 133, 'created_at': 1554610745000}

Демо: https://repl.it/@glhr/55557800

Это странно, я тоже удалил двойную косую черту, но это выдало мне ошибку, что-то в Scrapy. Хорошо, проверим и ответим в ближайшее время, спасибо!

Thinkerer 07.04.2019 15:44

Спасибо, это правильно. Ошибка связана с отступом, с которым я все еще пытаюсь разобраться. Я взял Python из JS, поэтому не знаю, насколько Python придирчив к отступам.

Thinkerer 07.04.2019 16:44

Я решил отступ, это внешняя проблема. Тем не менее, теперь он видит 200 http, но не сканирует и не выдает сообщений об ошибках, поэтому не знаю, в чем проблема. Я прикрепил отредактированный код и темы выше.

Thinkerer 07.04.2019 17:06

@Thinkerer Я обновил свой ответ рабочей реализацией синтаксического анализа. Вы также можете увидеть вывод в CSV-файле в демоверсии (в файлах слева).

glhr 07.04.2019 20:27

Спасибо за ссылку, очень ценю усилия, чтобы сделать это простым. Ссылка работает. Один вопрос, в какой части кода проверки вы замечаете json? Я пытался искать, но не смог найти. Я добавил .json к URL-адресу и попытался сделать дамп в анализаторе, но не увидел такой четкой иерархии.

Thinkerer 08.04.2019 17:50

Используйте Ctrl+U, чтобы просмотреть полный исходный код и выполнить поиск «данных» (включая двойные кавычки). Обратите внимание, что это огромный блок JSON.

glhr 08.04.2019 17:55

Другие вопросы по теме