У меня есть список из примерно 100 веб-страниц HTML (все они имеют разные структуры, такие как div, привязки, классы и т. д.), и я пытаюсь очистить заголовок каждой страницы (где заголовок находится под определенным div и классом). Для этого я использовал запросы на получение и Beautifulsoup, однако это занимает много времени (10 минут каждый раз, когда я хочу это сделать)!
Я использовал таймер, чтобы увидеть, что занимает больше всего времени: это запросы на получение. Судя по всему, Python (3.7) выполняет код один за другим, и, поскольку каждый запрос на получение занимает около 5-6 секунд, для выполнения ~ 100 запросов требуется примерно 500-600 секунд.
Я искал способы заставить эти запросы работать быстрее и наткнулся на множество различных решений. Тем не менее, общая тема, похоже, заключалась в том, что асинхронность моих запросов (чтобы все запросы запускались одновременно) решит проблему (за счет ускорения).
Для этого было много возможных решений, которые я читал в Интернете, в том числе: многопоточность, использование grequest, использование Scrapy, синтаксический анализ lxml и т. д. Однако я новичок в программировании и недостаточно квалифицирован, чтобы учиться и экспериментировать с каждым способом (на самом деле , я пытался следовать ответам на подобные вопросы на SO, но безуспешно), поэтому я не уверен, какой маршрут мне лучше выбрать.
Мне не нужно ничего необычного; все, что я хочу сделать, это извлечь заголовки из документов HTML в виде текста, а затем распечатать их. Мне не нужно загружать какие-либо файлы CSS, изображения, мультимедиа и т. д. Кроме того, я надеюсь, что код будет как можно более простым/голым. Как я могу сделать это как можно быстрее в Python? Я был бы признателен, если бы кто-нибудь мог предложить лучший путь (например, с использованием Scrapy) и дать краткое объяснение того, что я должен делать с помощью этого инструмента, чтобы получить результаты, на которые я надеюсь. Вам не нужно писать весь код для меня. Спасибо!






У Этот ответ, похоже, есть готовый для вырезания и вставки ответ. (Вы также, вероятно, могли бы увеличить размер пула потоков, если ваш HTML-запрос занимает около 5 секунд.) Для вашей точной проблемы код:
def crawlToCSV(URLrecord):
OpenSomeSiteURL = urllib2.urlopen(URLrecord)
Soup_SomeSite = BeautifulSoup(OpenSomeSiteURL, "lxml")
OpenSomeSiteURL.close()
return Soup_SomeSite.title.string
Создал бы в results список заголовков.
Быстрый поиск «асинхронного парсинга в python» привел к эта статья на медиуме Сантоша Хари. Пожалуйста, прочитайте эту статью, поскольку он дает объяснение того, как работает код.
Суть поста в следующем: используются библиотеки 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)
Одна из идей, которую я могу предложить, заключается в том, чтобы взять все URL-адреса в Csv и сохранить несколько заголовков, таких как path, title div, body div, div image в соответствии с вашими требованиями, и продолжать добавлять конкретный div (div class="title").
Бывший: ПУТЬ НАЗВАНИЕ РАЗДЕЛ ИЗОБРАЖЕНИЯ РАЗДЕЛ ТЕЛА РАЗДЕЛ
Точно так же вы можете указать все ссылки в одном CSV-файле и прочитать его через скрипт Python, чтобы все данные были извлечены.
loopв этой функцииfetch_all_urls(session, urls, loop)просто заполнитель и абсолютно ничего не делает, не так ли?