У меня есть список из примерно 100 веб-страниц HTML (все имеют разные структуры, такие как div, якоря, классы и т. Д.), И я пытаюсь очистить заголовок каждой страницы (где заголовок находится под определенным div и классом). Для этого я использовал запросы get и Beautifulsoup, однако это занимает много времени (10 минут каждый раз, когда я хочу это сделать)!

Я использовал таймер, чтобы увидеть, что занимает больше всего времени: это запросы get. Очевидно, Python (3.7) выполняет код один за другим, и, поскольку каждый запрос get занимает около 5-6 секунд, для выполнения ~ 100 запросов требуется примерно 500-600 секунд.

Я искал способы заставить эти запросы работать быстрее и нашел много разных решений. Тем не менее, общей темой было то, что выполнение моих запросов асинхронно (чтобы все запросы запускались одновременно) решило проблему (сделав ее быстрее).

Было много возможных решений для этого, которые я читал в Интернете, включая: многопоточность, использование grequest, использование Scrapy, анализ lxml и т. Д. Однако я новичок в программировании и не достаточно опытен, чтобы учиться и экспериментировать со всеми способами (на самом деле Я попытался проследить ответы на похожие вопросы на SO, но безуспешно), поэтому я не уверен, какой путь мне лучше всего выбрать.

Мне не нужно ничего особенного; все, что я хочу сделать, это извлечь заголовки из документов HTML в виде текста и затем распечатать их. Мне не нужно загружать какие-либо CSS-файлы, изображения, мультимедиа и т. Д. Кроме того, я надеюсь сохранить код как можно более простым и понятным. Как я могу сделать это как можно быстрее в Python? Я был бы признателен, если бы кто-то мог предложить лучший путь (например, с помощью Scrapy) и дать краткое объяснение того, что я должен делать, используя этот инструмент, чтобы получить результаты, на которые я надеюсь. Вам не нужно выписывать весь код для меня. Благодарность!

1
George Orwell 8 Июл 2019 в 07:05

3 ответа

Лучший ответ

В этом ответе, похоже, есть готовый к употреблению ответ. (Возможно, вы также можете увеличить размер пула потоков, если ваш HTML-запрос занимает около 5 секунд.) Для вашей конкретной проблемы, код:

def crawlToCSV(URLrecord):
    OpenSomeSiteURL = urllib2.urlopen(URLrecord)
    Soup_SomeSite = BeautifulSoup(OpenSomeSiteURL, "lxml")
    OpenSomeSiteURL.close()

    return Soup_SomeSite.title.string

Создает в results список заголовков.

1
Ken Y-N 8 Июл 2019 в 04:26

Быстрый поиск "асинхронной очистки в Python" привел к эта статья в среде автора Santhosh Hari. Пожалуйста, прочитайте эту статью, так как он объясняет, как работает код.

Суть сообщения заключается в использовании библиотек asyncio и aiohttp.

import asyncio
import aiohttp
import requests

async def fetch_url(session, url):
    async with session.get(url, timeout=60 * 60) as response:
        return await response.text()

async def fetch_all_urls(session, urls, loop):
    results = await asyncio.gather(*[fetch_url(session, url) for url in urls],
    return_exceptions=True)
    return results

def get_htmls(urls):
    if len(urls) > 1:
        loop = asyncio.get_event_loop()
        connector = aiohttp.TCPConnector(limit=100)
        with aiohttp.ClientSession(loop=loop, connector=connector) as session:
            htmls = loop.run_until_complete(fetch_all_urls(session, urls, loop))
        raw_result = dict(zip(urls, htmls))
    else:
        headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36'}
        raw_result = requests.get(urls[0], headers=headers).text

    return raw_result

result_dict = get_htmls(url_list)
1
SIM 8 Июл 2019 в 10:39

Одна из идей, которую я могу предложить, - это взять все URL-адреса в Csv и сохранить несколько заголовков, таких как path, title div, body div, image div в соответствии с вашими требованиями и продолжать добавлять определенный div (div class = "title").

Пример: PATH TITLE DIV IMAGE DIV BODY DIV

Точно так же вы можете дать все ссылки в одном CSV-файле и прочитать его через скрипт Python, чтобы все данные были извлечены.

1
prasanna batchu 8 Июл 2019 в 05:04