Ошибка 501 ScraPy - код статуса HTTP не обрабатывается или не разрешен - PullRequest
1 голос
/ 07 апреля 2019

Получил ошибку выше.Пробежал через SO и только на 403 или 404 обсуждались ошибки.

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

  • отредактировал user_agent для моей строки
  • проверил rodts.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)

1 Ответ

3 голосов
/ 07 апреля 2019

Эта проблема не имеет ничего общего с вашей реализацией кода, это просто опечатка в 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...