Почему запрос, сделанный с помощью библиотеки requests, проходит успешно, а аналогичный запрос с использованием aiohttp возвращает ошибку 403?

Я столкнулся с непонятной проблемой: при выполнении HTTP-запроса с помощью библиотеки `requests` (как сессией, так и без) запрос проходит успешно, однако при использовании `aiohttp` я получаю ответ с кодом 403. Ниже представлена минимальная версия кода для проверки (вы можете подставить свои куки и заголовки): 

```python
import requests
import aiohttp
import asyncio
from bs4 import BeautifulSoup, ResultSet, Tag

cookies = {}

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:129.0) Gecko/20100101 Firefox/129.0',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8',
    'Accept-Language': 'ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3',
    'Referer': 'https://www.vseinstrumenti.ru/brand/bosch-3/',
    'Connection': 'keep-alive',
    'Upgrade-Insecure-Requests': '1',
    'Sec-Fetch-Dest': 'document',
    'Sec-Fetch-Mode': 'navigate',
    'Sec-Fetch-Site': 'same-origin',
    'Priority': 'u=0, i',
}

session = requests.Session()

resp = session.get('https://www.vseinstrumenti.ru/brand/bosch-3/page1/', cookies=cookies, headers=headers)
assert resp.status_code == 200

def parse(text):
    soup = BeautifulSoup(text, features='lxml')

    items: ResultSet[Tag] = soup.find(
        'div', id='product-listing-top'
    ).find(
        'div', attrs={'data-qa': 'listing'}
    ).find_all('div', attrs={'data-qa': 'products-tile'})

    print(items)

print('REQUESTS')
parse(resp.text)

async def gd():
    async with aiohttp.ClientSession(
        'https://www.vseinstrumenti.ru',
        cookies=cookies,
        headers=headers
    ) as session:
        async with session.get('/brand/bosch-3/page1/') as response:
            # Здесь должен быть обработчик ответа
```

Как можно объяснить, почему запрос через `aiohttp` возвращает ошибку, в то время как `requests` работает корректно?
  • 28 августа 2024 г. 13:24
Ответы на вопрос 2
Ошибка 403 обычно означает, что доступ к ресурсу запрещен, и это может происходить по нескольким причинам, особенно когда дело касается различных библиотек для выполнения HTTP-запросов, таких как `requests` и `aiohttp`. Давайте рассмотрим возможные причины и решения для вашей проблемы.

### Причины различий в поведении

1. **Заголовки запроса**:
   - Хотя вы передаете одинаковые заголовки в обоих случаях, иногда различия в их форматировании могут иметь значение, особенно для заголовков, которые определяют поведение или права доступа.

2. **Куки**:
   - Убедитесь, что куки, передаваемые с помощью `aiohttp`, действительно те же, что и в `requests`. Иногда значение куки может изменяться между сессиями.

3. **Настройки сессии**:
   - В `aiohttp.ClientSession` необходимо обязательно передавать базовый URL в `get`, чтобы правильно совершить запрос.

4. **Параметры прокси и настройки сети**:
   - Если вы используете прокси (или ваше приложение работает за корпоративным фаерволом), это тоже может вызвать проблемы с доступом, особенно для асинхронных запросов.

5. **Ограничения на стороне сервера**:
   - Некоторые серверы могут блокировать запросы, если они приходят с использованием асинхронного клиента. Например, сервер может использовать средства защиты, такие как Rate Limiting или блокировка ботов.

### Решение проблемы

1. Проверьте и убедитесь, что куки одинаковы:
   ```python
   print(cookies)
   ```

2. Проверьте, все ли заголовки правильно передаются:
   ```python
   async def gd():
       async with aiohttp.ClientSession(headers=headers) as session:
           async with session.get('https://www.vseinstrumenti.ru/brand/bosch-3/page1/', cookies=cookies) as response:
               print(response.status)
               if response.status == 200:
                   text = await response.text()
                   parse(text)
               else:
                   print(f'Error: {response.status}')
   ```

3. Попробуйте добавить/изменить заголовки, возможно, некоторые из них (например, `Origin`, `DNT`, `Te`) также важны для работоспособности запроса.

4. Отлаживайте или отлавливайте ответ от сервера, чтобы понять, почему он возвращает 403. Вы можете использовать `response.text()` к возврату тела ответа для дополнительной информации.

Пример изменения функции `gd`:
```python
async def gd():
    async with aiohttp.ClientSession() as session:
        async with session.get('https://www.vseinstrumenti.ru/brand/bosch-3/page1/', cookies=cookies, headers=headers) as response:
            print(response.status)
            if response.status == 200:
                text = await response.text()
                parse(text)
            else:
                print(f'Error: {response.status}')
```

### Заключение

Проблема может заключаться в различиях в том, как `requests` и `aiohttp` обрабатывают заголовки, куки или даже выполнение запросов на уровне сетевой стека. Проверяя эти аспекты, вы сможете найти причину и исправить ошибку.
Значит тебя не пускают на этот ресурс
Похожие вопросы