Тайм-аут чтения при попытке запросить страницу - PullRequest
0 голосов
/ 02 марта 2020

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

requests.exceptions.ReadTimeout: HTTPSConnectionPool(host='www.somewebsite.com', port=443): Read timed out. (read timeout=None)

Мой код выглядит как следующий

from bs4 import BeautifulSoup
from random_user_agent.user_agent import UserAgent
from random_user_agent.params import SoftwareName, OperatingSystem
import requests

software_names = [SoftwareName.CHROME.value]
operating_systems = [OperatingSystem.WINDOWS.value, OperatingSystem.LINUX.value]
user_agent_rotator = UserAgent(software_names=software_names, operating_systems=operating_systems, limit=100)
pages_to_scrape = ['https://www.somewebsite1.com/page', 'https://www.somewebsite2.com/page242']

for page in pages_to_scrape:
  time.sleep(2)
  page = requests.get(page, headers={'User-Agent':user_agent_rotator.get_random_user_agent()})
  soup = BeautifulSoup(page.content, "html.parser")
  # scrape info 

Как вы можете видеть из моего кода, я даже использую Time, чтобы перевести мой сценарий на пару секунд, прежде чем запросить другую страницу. Я также использую случайный user_agent. Я не уверен, смогу ли я сделать что-нибудь еще, чтобы убедиться, что я никогда не получаю ошибку Тайм-аут чтения.

Я также сталкивался с этим , но, похоже, они предлагают добавить дополнительные значения к заголовки, но я не уверен, что это универсальное c решение, потому что это может быть необходимо указать c от веб-сайта к веб-сайту. Я также прочитал на другом SO Post , что мы должны base64 запрос и повторить попытку. Это пошло мне на ум, так как я понятия не имел, как это сделать, и у человека не было примера, приведенного здесь.

Любой совет тех, кто имеет опыт в очистке, был бы очень признателен.

Ответы [ 2 ]

1 голос
/ 06 марта 2020

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

curl -s -o /dev/null -D - https://www.uniqlo.com/us/en/men/t-shirts

enter image description here

, который будет блокировать ваши запросы, если он не действителен User-Agent и должен быть stable. вам не нужно менять его при каждом запросе. Кроме того, вам нужно будет использовать requests.Session(), чтобы сохранить session и не заставлять слой TCP отбрасывать пакеты, я смог отправить 1k запросов в течение секунды и не был заблокирован. даже я проверил, заблокирует ли bootstrap запрос, если я проанализировал источник HTML, но он этого не сделал.

, получив уведомление, что я запустил все свои тесты, используя Google DNS, что никогда не вызовет задержка моего потока, которая может firewall отбросить запросы и определить его как DDOS attack. Также нужно отметить один момент. DO NOT USE timeout=None, поскольку это приведет к тому, что запрос будет ждать ответа вечно, когда на серверной стороне брандмауэр автоматически обнаруживает любой TCP listener, который в pending state, и автоматически отбрасывает его и блокирует origin IP, которым вы являетесь. в зависимости от настроенного времени :) -

import requests
from concurrent.futures.thread import ThreadPoolExecutor
from bs4 import BeautifulSoup


def Test(num):
    print(f"Thread# {num}")
    with requests.session() as req:
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:73.0) Gecko/20100101 Firefox/73.0'}
        r = req.get(
            "https://www.uniqlo.com/us/en/men/t-shirts", headers=headers)
        soup = BeautifulSoup(r.text, 'html.parser')
        if r.status_code == 200:
            return soup.title.text
        else:
            return f"Thread# {num} Failed"


with ThreadPoolExecutor(max_workers=20) as executor:
    futures = executor.map(Test, range(1, 31))
    for future in futures:
        print(future)

Запустить онлайн

0 голосов
/ 02 марта 2020

Исключения ReadTimeout обычно возникают из-за следующих действий:

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

Похоже, вы делаете 1 запрос каждые 2 секунды. Для некоторых сайтов это нормально, другие могут назвать это атакой отказа в обслуживании. Google, например, будет замедлять или блокировать часто встречающиеся запросы.

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

Чтобы решить эту проблему, попробуйте следующее:

  1. Увеличение времени между запросами. Для Google у меня работает 30-45 секунд, если я не использую API
  2. Уменьшите количество одновременных запросов.
  3. Посмотрите на сетевые запросы, возникающие при посещении сайта в вашем браузере, и попробуйте имитировать c их.
  4. Используйте пакет, например, селен, чтобы ваша деятельность выглядела как бот.
...