Повторяющаяся ошибка HTTP 413 при очистке нескольких страниц - PullRequest
1 голос
/ 09 апреля 2019

Я убираю сообщения из Wykop.pl ('Польский Reddit'), просматривая несколько страниц, которые были возвращены, когда я искал свое ключевое слово на сайте.Я написал цикл для итерации моего целевого контента для каждой страницы;однако цикл завершается на определенных страницах (последовательно) с ошибкой «Ошибка HTTP 413: запрос слишком велик».

Я пытался очистить проблемные страницы по отдельности, но одно и то же сообщение об ошибке продолжало повторяться.Чтобы обойти это, я должен был установить свои диапазоны вручную для сбора данных, но ценой пропуска широкого диапазона данных, и я хотел бы знать, есть ли решение Pythonic для решения этой ошибки.Я также пробовал делать более длинные паузы, так как, возможно, я рискнул отправить слишком много запросов, но, похоже, это не так.

from time import sleep
from random import randint
import requests
from requests import get
from bs4 import BeautifulSoup
from mtranslate import translate
from IPython.core.display import clear_output


from mtranslate import translate
posts = []
votes = []
dates = []
images = []
users = []

start_time = time()
requests = 0
pages = [str(i) for i in range(1,10)]

for page in pages:
    url = "https://www.wykop.pl/szukaj/wpisy/smog/strona/" + page + "/"
    response = get(url)

    # Pause the loop
    sleep(randint(8,15))

        # Monitor the requests
    requests += 1
    elapsed_time = time() - start_time
    print('Request:{}; Frequency: {} requests/s'.format(requests, requests/elapsed_time))
    clear_output(wait = True)
    # Throw a warning for non-200 status codes
    if response.status_code != 200:
        warn('Request: {}; Status code: {}'.format(requests, response.status_code))
    # Break the loop if the number of requests is greater than expected
    if requests > 10:
        warn('Number of requests was greater than expected.')
        break


    soup = BeautifulSoup(response.text, 'html.parser')
    results = soup.find_all('li', class_="entry iC")


    for result in results:
            # Error handling
            try:

                post = result.find('div', class_="text").text
                post = translate(post,'en','auto')
                posts.append(post)

                date = result.time['title']
                dates.append(date)

                vote = result.p.b.span.text
                vote = int(vote)
                votes.append(vote)

                user = result.div.b.text
                users.append(user)

                image = result.find('img',class_='block lazy')
                images.append(image)

            except AttributeError as e:
                print(e)

Если бы я мог запустить скрипт сразу, яустановил бы диапазон от 1 до 163 (так как у меня есть результаты на 163 страницы постов с упоминанием моего ключевого слова интереса).Поэтому мне пришлось устанавливать меньшие диапазоны для поэтапного сбора данных, но опять же за счет пропуска на страницах данных.

В качестве непредвиденного обстоятельства я могу выбрать из выделенных проблемных страниц загруженные HTML-документы на моем рабочем столе.

Ответы [ 2 ]

0 голосов
/ 10 апреля 2019

ОК, так вот в чем подвох:

Ошибка 413 связана не с Wykop, веб-сайтом, подлежащим очистке, а с пакетом mtranslate, который использует API Google Translate. В моем исходном коде произошло то, что, когда Wykop был очищен, он переводил сообщения с польского на английский. Тем не менее, API перевода Google имеет ограничение примерно 100 000 символов на 100 секунд на пользователя. Поэтому, когда код достиг 13-й страницы, mtranslate превысил лимит запросов для Google Translate . Следовательно, почему решение Мартина отлично работает, собирая данные с отключенной функцией перевода .

Я пришел к такому выводу, когда использовал модуль для перевода постов, хранящихся в кадре данных, так как я столкнулся с той же ошибкой на отметке 8% в моем цикле перевода.

0 голосов
/ 09 апреля 2019

Возможно, вы установили ограничение IP-адреса.При запуске скрипта он работает нормально для меня без ограничения скорости (на данный момент).Тем не менее, я бы порекомендовал вам использовать requests.Session() (вам нужно изменить переменную requests или она переопределит импорт).Это может помочь уменьшить возможные проблемы утечки памяти.

Так, например:

from bs4 import BeautifulSoup
from time import sleep
from time import time
from random import randint
import requests

posts = []
votes = []
dates = []
images = []
users = []

start_time = time()
request_count = 0
req_sess = requests.Session()

for page_num in range(1, 100):
    response = req_sess.get(f"https://www.wykop.pl/szukaj/wpisy/smog/strona/{page_num}/")

    # Pause the loop
    #sleep(randint(1,3))

    # Monitor the requests
    request_count += 1
    elapsed_time = time() - start_time
    print('Page {}; Request:{}; Frequency: {} requests/s'.format(page_num, request_count, request_count/elapsed_time))

    #clear_output(wait = True)
    # Throw a warning for non-200 status codes
    if response.status_code != 200:
        print('Request: {}; Status code: {}'.format(requests, response.status_code))
        print(response.headers)

    # Break the loop if the number of requests is greater than expected
    #if requests > 10:
    #    print('Number of requests was greater than expected.')
    #    break

    soup = BeautifulSoup(response.text, 'html.parser')
    results = soup.find_all('li', class_="entry iC")

    for result in results:
        # Error handling
        try:
            post = result.find('div', class_="text").text
            #post = translate(post,'en','auto')
            posts.append(post)

            date = result.time['title']
            dates.append(date)

            vote = result.p.b.span.text
            vote = int(vote)
            votes.append(vote)

            user = result.div.b.text
            users.append(user)

            image = result.find('img',class_='block lazy')
            images.append(image)

        except AttributeError as e:
            print(e)

Получил следующий вывод:

Page 1; Request:1; Frequency: 1.246137372973911 requests/s
Page 2; Request:2; Frequency: 1.3021880233774552 requests/s
Page 3; Request:3; Frequency: 1.2663757427416629 requests/s
Page 4; Request:4; Frequency: 1.1807827876080845 requests/s                
.
.
.
Page 96; Request:96; Frequency: 0.8888853607003809 requests/s
Page 97; Request:97; Frequency: 0.8891876183362001 requests/s
Page 98; Request:98; Frequency: 0.888801819672809 requests/s
Page 99; Request:99; Frequency: 0.8900784741536467 requests/s                

Это также работало нормально, когда я началс гораздо более высокими номерами страниц.Теоретически, когда вы получаете код состояния ошибки 413, теперь он должен отображать заголовки ответа.В соответствии с RFC 7231 сервер должен вернуть поле заголовка Retry-After, которое можно использовать для определения продолжительности отката до следующего запроса.

...