Как выполнить парсинг номеров телефонов с сайта OLX?

Здравствуйте! У меня возникла проблема с парсингом номеров телефонов на OLX. Могу ли я получить помощь с этим вопросом? Вот код, который я использую: 

<pre><code class="python">import asyncio
import aiohttp
import csv
from bs4 import BeautifulSoup
from tqdm import tqdm

HEADERS = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36"
}

# Читаем список ссылок
with open('product_links.txt', 'r') as f:
    links = [line.strip() for line in f]

sem = asyncio.Semaphore(30)  # Лимит одновременных запросов

async def fetch(session, url):
    async with sem:
        try:
            async with session.get(url, headers=HEADERS, timeout=10) as response:
                return await response.text()
        except Exception as e:
            print(f"[Ошибка запроса] {url}: {e}")
            return None

async def get_phone_number(session, ad_id):
    api_url = f'https://www.olx.ua/api/v1/offers/{ad_id}/phones/'
    async with sem:
        try:
            async with session.get(api_url, headers=HEADERS, timeout=10) as response:
                if response.status == 200:
                    data = await response.json()
                    phones = data.get("data", {}).get("phones", [])
                    return phones[0] if phones else "Нет номера"
        except Exception as e:
            print(f"[Ошибка запроса] {api_url}: {e}")
            return "Ошибка запроса"
    return "Нет номера"

def get_subcategory(soup):
    category_tag = soup.select_one(
        "div#hydrate-root div.css-1ek5um8 div.css-118kolg div.css-16gd35i "
        "div.css-6rrh1l nav[role='navigation'] ol.css-xv75xi li.css-7dfllt:nth-of-type(4) a.css-tyi2d1"
    )
    return category_tag.get_text(strip=True) </code></pre>
  • 8 марта 2025 г. 7:14
Ответы на вопрос 2
Парсинг сайтов, таких как OLX, может быть сложной задачей, так как они часто используют различные методы для защиты от автоматизированного доступа, и могут изменять свои API или HTML-структуру. Также важно помнить оLegal и Ethical аспектах парсинга, соблюдая правила и условия использования сайта.

В качестве предложения, я могу помочь вам улучшить ваш код. Ниже приведен пример, как можно выполнить парсинг номеров телефонов с OLX, с использованием вашего кода в качестве основы. 

### Обновленный код

```python
import asyncio
import aiohttp
import csv
from bs4 import BeautifulSoup
from tqdm import tqdm

HEADERS = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36"
}

# Читаем список ссылок
with open('product_links.txt', 'r') as f:
    links = [line.strip() for line in f]

sem = asyncio.Semaphore(30)  # Лимит одновременных запросов

async def fetch(session, url):
    async with sem:
        try:
            async with session.get(url, headers=HEADERS, timeout=10) as response:
                return await response.text()
        except Exception as e:
            print(f"[Ошибка запроса] {url}: {e}")
            return None

async def get_phone_number(session, ad_id):
    api_url = f'https://www.olx.ua/api/v1/offers/{ad_id}/phones/'
    async with sem:
        try:
            async with session.get(api_url, headers=HEADERS, timeout=10) as response:
                if response.status == 200:
                    data = await response.json()
                    phones = data.get("data", {}).get("phones", [])
                    return phones[0] if phones else "Нет номера"
                else:
                    print(f"[Ошибка API] {api_url}: {response.status}")
                    return "Нет номера"
        except Exception as e:
            print(f"[Ошибка запроса] {api_url}: {e}")
            return "Ошибка запроса"

async def main():
    async with aiohttp.ClientSession() as session:
        tasks = []
        for link in links:
            # Извлекаем идентификатор объявления (ad_id)
            ad_id = link.split("/")[-1]  # предполагается, что ID является последней частью URL
            tasks.append(get_phone_number(session, ad_id))

        results = await asyncio.gather(*tasks)
        
        for link, phone in zip(links, results):
            print(f"{link}: {phone}")

if __name__ == "__main__":
    asyncio.run(main())
```

### Объяснение изменений:

1. **Проверка статуса ответа**: Я добавил вывод сообщения в случае, если API возвращает статус, отличный от 200, чтобы понимать, когда что-то пошло не так.

2. **Главная функция**: Создана основная асинхронная функция `main`, которая собирает все задачи и собирает результаты параллельно.

3. **Чтение `ad_id`**: Поскольку идентификатор объявления (ad_id) обычно является частью URL, он извлекается из ссылки.

### Замечания:

- Убедитесь, что вы соблюдаете правила использования OLX. Если сайт запрещает автоматизированный доступ, вам следует прекратить попытки парсинга.
- Используйте задержку между запросами, чтобы не перегружать сервер и избежать блокировок.
- Рассмотрите возможность использования методов, предоставляемых самим OLX, если такие есть (например, API, если они доступны для общего доступа).

Пожалуйста, не забудьте проверить актуальность кода, так как OLX может изменить структуру своих страниц или API в любое время.
тебе нужно сперва отправить запросы на челендж и эксченддж для получения токены и только потом отправлять запрос на поучение номера @tipa_Wolf 
Также нужно менять ип https://dash.makeadsafe.com/invite/9wsYA6lD?next=proxy мультипорт каждый запрос новый ип
Похожие вопросы