Это первая из четырех статей, направленных на решение проблемы выявления вспышек заболеваний путем извлечения заголовков новостей из популярных источников новостей.
Заголовки новостей были выбраны в качестве основы для алгоритма неконтролируемой кластеризации из-за его способности кратко представлять информацию. Хотя просеивание новостей само по себе позволило бы получить больше географических местоположений, объем вычислительной обработки и пропускная способность перевешивают преимущества, которые они предоставляют. Чтобы найти самые популярные источники новостей, были выбраны две статьи Feedspot (100 лучших новостных веб-сайтов США и 100 лучших мировых новостных веб-сайтов), содержащие список из ста лучших источников новостей в мире и США; эта статья постоянно обновляется, чтобы обеспечить наличие в ней самой последней информации. Этот метод действительно представляет предвзятость, поскольку некоторые новостные веб-сайты, такие как The Los Angeles Times, обычно сообщают новости о своем городе, создавая искаженные кластеры; соответственно, были удалены новостные веб-сайты, относящиеся к определенному городу.
Подробное объяснение кода приведено ниже.
Шаг 1. Установите и импортируйте соответствующие библиотеки.
!pip install bs4 !pip install django from bs4 import BeautifulSoup as bs import urllib.request from django.core.validators import URLValidator from django.core.exceptions import ValidationError import time from datetime import datetime import boto3
Шаг 2. Инициализируйте и очистите корзину S3 (необязательно)
С помощью библиотеки boto3 и учетных данных конфигурации учетной записи AWS объект S3 очищается и помещается в корзину S3. Этот шаг не требуется, если интеграция с AWS не требуется.
s3 = boto3.resource( 's3', region_name='us-east-1', aws_access_key_id=*HIDDEN*, aws_secret_access_key=*HIDDEN* ) content = "" s3.Object('headlines', 'headline.txt').put(Body=content)
Шаг 3. Создайте функцию для извлечения веб-сайтов.
Сначала, используя библиотеку urllib, код открывает URL-адрес и преобразует содержимое веб-сайта в HTML. Затем с помощью библиотеки Beautiful Soup HTML анализируется, а гиперссылки извлекаются из HTML-кода. Эти гиперссылки определяются путем нахождения блоков «a» в коде HTML. При реализации библиотеки Django URL-адреса гиперссылок проверяются, фильтруются на основе URL-адреса исключения и добавляются в массив. Затем возвращается этот массив URL-адресов.
def extractWebsites(url, exceptionURL): try: webUrl = urllib.request.urlopen(url) data = webUrl.read() soup = bs(data) arr = [] for link in soup.find_all('a'): validate = URLValidator() href = link.get('href') if (href != None): try: validate(href) if (href.find(exceptionURL) == -1): arr.append(href) except ValidationError as exception: continue return arr except: return []
Шаг 4. Создайте функцию, которая ищет в URL-адресе определенные ключевые слова.
Функция выполняет итерацию по массиву ключевых слов и возвращает истину, если какое-либо из ключевых слов находится в URL-адресе.
def search_array(url, arrOfPoss): for index in arrOfPoss: if (url.find(index.capitalize()) != -1 or url.find( index.lower()) != -1): return True return False
Шаг 5. Извлеките заголовки
Во-первых, ряд новостных каналов выбирается из 100 лучших американских и мировых новостных сайтов Feedspot. Затем этот массив повторяется с помощью функции extractWebsites для поиска подходящих веб-сайтов, имеющих отношение к COVID-19. «Интерактивный» выбран в качестве URL-адреса исключения, поскольку они не содержат релевантных заголовков. Другие заголовки фильтруются с помощью функции search_array с набором ключевых слов COVID-19. Эти отфильтрованные заголовки сохраняются в новом массиве с именем covid_urls.
Снова используя функцию extractWebsites, выполняется итерация covid_urls для поиска дополнительных веб-сайтов, связанных с COVID. Чтобы сократить время выполнения, реализован счетчик, который останавливается, если необходимо пройти слишком много веб-сайтов. Кроме того, если эта процедура занимает больше десяти минут, внутренний цикл for завершается. И снова в качестве execptionURL выбран «интерактивный», а заголовки фильтруются с помощью функции search_array с тем же набором ключевых слов COVID-19. Эти отфильтрованные заголовки сохраняются в новом массиве с именем new_covid_urls.
Этот процесс повторяется еще раз, чтобы оптимизировать количество извлекаемых релевантных заголовков. Отфильтрованные заголовки сохраняются в другом массиве с именем newest_covid_urls. Чтобы сохранить соответствующие заголовки в объекте S3, были повторены URL-адреса внутри new_covid_urls и newest_covid_urls. Для каждого веб-сайта в этих массивах URL-адрес был преобразован в HTML, чтобы определить заголовок URL-адреса. После проверки на повторение в массиве headlines заголовок был добавлен внутри объекта S3 и массива headlines. Последний массив headlines был помещен внутри объекта S3.
headlines = [] for index in data: new_data = extractWebsites(index, 'interactive') covid_urls = [] arr_keywords = ['coronavirus', 'COVID', 'covid', 'pandemic', 'epidemic', 'disease', 'SARS', 'sars', 'virus'] for index1 in new_data: if (search_array(index1, arr_keywords)): covid_urls.append(index1) count = 0 for val in covid_urls: if count > 13: break future = time.time() + 600 newer_data = extractWebsites(val, "interactive") new_covid_urls = [] for index1 in newer_data: if (search_array(index1, arr_keywords)): new_covid_urls.append(index1) for value in new_covid_urls: if (time.time()) > future: break newest_data = extractWebsites(value, "interactive") newest_covid_urls = [] for index2 in newest_data: if (time.time()) > future: break if (search_array(index2, arr_keywords)): newest_covid_urls.append(index2) for urls1 in newest_covid_urls: if ((time.time()) > future): break try: webUrl = urllib.request.urlopen(urls1) data = webUrl.read() soup = bs(data) try: title = soup.find('title').string if (title not in headlines) and (search_array(title, arr_keywords)): headlines.append(title) content = "\n".join(headlines) s3.Object('headlines', 'headline.txt').put(Body=content) except TypeError as exception: print("Exception occured") continue except: continue for urls in new_covid_urls: if (time.time()) > future: break try: webUrl = urllib.request.urlopen(urls) data = webUrl.read() soup = bs(data) try: title = soup.find('title').string if (title not in headlines) and (search_array(title, arr_keywords)): headlines.append(title) content = "\n".join(headlines) s3.Object('headlines', 'headline.txt').put(Body=content) except: continue except: continue content = "\n".join(headlines) s3.Object('headlines', 'headline.txt').put(Body=content)
В зависимости от того, выполняется ли этот код на вашем локальном компьютере или в экземпляре AWS Sagemaker, время выполнения кода может варьироваться от нескольких часов до нескольких дней. Код в настоящее время работает на экземпляре ml.c5.xlarge с хранилищем EBS 20 ГБ; обратите внимание, что работа на Sagemaker требует дополнительных затрат в отличие от вашей локальной машины.
Применение этого кода огромно, так как заголовки можно извлекать по любому диапазону тем. В интересах проекта были изменены только ключевые слова COVID-19, но это можно легко изменить, изменив ключевые слова. Код можно легко изменить так, чтобы он соответствовал количеству заголовков, которые вы хотите получить. Можно добавить альтернативные веб-сайты для дальнейшего расширения данных или соответственно изменить количество ключевых слов.
Щелкните эту ссылку для доступа к репозиторию Github с подробным объяснением кода: Github.