Анализ пропавших без вести лиц в США
Table Of Content
На веб-сайтах, которые мы посещаем каждый день, есть множество полезных данных, но каждый сайт может иметь свою собственную структуру и форму, что затрудняет быстрое извлечение нужных данных. В этой статье я покажу вам, как я собрал данные о пропавших без вести лицах с веб-сайта Международный центр по идентификации и поиску пропавших без вести лиц с помощью Scrapy, а также как я очистил данные и проанализировал пространственно-временные данные с помощью инструментов ArcGIS.
Парсинг веб-сайта
Scrapy - это фреймворк с открытым исходным кодом для извлечения нужных данных с веб-сайтов. Рекомендую прочитать официальное руководство, если вы не знакомы с ним. Для работы с Scrapy требуется Python 3.6+ и я установил его с помощью Anaconda в командной строке:
conda install -c conda-forge scrapy
На веб-странице, которую я парсил, перечислены пропавшие без вести мужчины в США в хронологическом порядке с 1881 года по 2020 год. Для каждого человека есть ссылка на его отдельную страницу с описанием, таким как имя, классификация дела, дата пропажи, последнее место видения, дата рождения, возраст и т. д. Моя цель заключалась в извлечении интересующих меня данных описания с каждой отдельной страницы пропавших без вести лиц.
В директории созданного проекта перезапишите файл items.py с элементами, которые вы хотите извлечь с сайта. Меня интересовали такие элементы, как имя, классификация дела, дата пропажи, последнее место видения, дата рождения, возраст, раса, пол, рост и вес с каждой отдельной страницы. Файл items.py был перезаписан следующим образом, чтобы извлеченные данные сохранялись в определенном классе элементов:
import scrapy
class WantedItem(scrapy.Item):
name = scrapy.Field()
case = scrapy.Field()
since = scrapy.Field()
location = scrapy.Field()
DOB = scrapy.Field()
age = scrapy.Field()
race = scrapy.Field()
gender = scrapy.Field()
height = scrapy.Field()
weight = scrapy.Field()
- Определение класса Spider
В созданном проекте есть папка с именем spiders, в которой вы сохраняете свой код парсинга, который Scrapy использует для извлечения информации с веб-страницы. В коде парсинга есть две основные компоненты. Во-первых, определите URL веб-страницы и извлеките URL для каждой отдельной страницы человека. Для выбора элементов из HTML-документов использовались XPath. Код показан ниже:
# определение URL главной страницы
start_urls = ["[http://www.doenetwork.org/mp-chrono-us-males.php](http://www.doenetwork.org/mp-chrono-us-males.php)"]# извлечение отдельных URL
def parse(self, response):
for href in response.xpath("//div[contains([@id](http://twitter.com/id),'container')]/ul
[contains([@class](http://twitter.com/class), 'rig')]/li/a//@href"):
url = href.extract()
yield scrapy.Request(url, callback=self.parse_dir_contents)
Второй компонент - это итеративное извлечение текста с каждой отдельной веб-страницы с помощью следующего кода:
infor_list = response.xpath("//p/text()").getall()
При извлечении нужного текста извлекались также тексты (‘\n’ или ‘\n\n’) новой строки из HTML. Был создан новый список для удаления строк, содержащих ‘\n’ или ‘\n\n’, с помощью следующего кода:
new_infor = []
for a in infor_list:
if '\n' not in a:
new_infor.append(a)
- Запуск Spider и вывод данных
Введите следующий код в командной строке, чтобы запустить Scrapy, и извлеченные данные будут выведены в CSV-файл.
scrapy crawl my_scraper -o results.csv
Снимок экрана извлеченных данных показан ниже:
Очистка данных
Перед анализом данных, полученных с веб-сайта, необходимо очистить набор данных. Хотя каждый элемент может иметь свои собственные процедуры очистки, сначала были удалены данные, отсутствующие или неизвестные.
Возраст
Извлеченные данные о возрасте были в форме "xx лет" или "xx месяцев" (например, 27 лет). Чтобы получить возраст в одинаковом формате, сначала я разделил числовую часть от текстовой части (лет/месяцев). Затем разделил число на 12, если текстовая часть была "месяцев". Наконец, удалил текстовую часть и оставил только числовую часть с тем же единицей измерения (год).
Вес
Некоторые извлеченные данные о весе были в диапазоне (например, 140-150 фунтов). Для последующего анализа был сохранен только нижний предел.
Последнее место видения
Большинство данных о последнем месте видения были в форме "город/округ/штат" (например, Чардон, округ Гиога, Огайо). Поскольку меня интересовала только информация о штате, я разделил место по запятой и оставил только информацию о штате.
Рост
Рост был в формате фут-дюйм (например, 7' 1"). Я преобразовал их в дюймовую единицу. Например, для 7' 1" сначала я разделил строку по апострофу, затем умножил 7' на 12, что равно 84 дюймам. Рост в дюймах - это сумма 84 и 1.
Анализ данных
После очистки данных в наборе было 1893 пропавших без вести мужчин в диапазоне от 1905 года до 2020 года. Сначала я рассмотрел распределение пропавших без вести лиц по годам. Диаграмма рассеяния пропавших без вести лиц по году последнего видения с указанием возраста показана ниже. Из графика видно, что большинство данных приходится на период с 1970-х по 2000 годы.
Во-вторых, я сравнил данные между штатами, чтобы получить некоторое представление. Количество пропавших без вести лиц показано ниже по штатам, при этом Калифорния имеет наибольшее количество пропавших случаев, а Техас и Флорида занимают второе и третье места.
На карте ниже также показано количество пропавших без вести лиц в разных штатах.
Затем я рассмотрел возраст пропавших лиц, когда они были объявлены пропавшими, в разных штатах. Была построена диаграмма размаха, показывающая распределение возраста для каждого штата, и на карте также был показан средний возраст пропавших мужчин в разных штатах.
С использованием пространственно-временной информации в наборе данных, для визуализации количества пропавших лиц в каждом штате по годам (1955-2015), была использована ArcGIS. На начальном этапе этой статьи показано количество пропавших лиц в каждом штате по годам. В наборе данных было мало случаев до 1955 года и после 2015 года. Поэтому иллюстрируются только случаи пропажи между 1955 и 2015 годами, и они подсчитывались каждые пять лет.