Получение данных из диаграммы, отображаемой на веб-сайте - PullRequest
7 голосов
/ 07 мая 2011

Меня попросили нарисовать график, подобный этому

enter image description here

с использованием латекса (точнее, tikz и / или pgf).Это не было бы проблемой, если бы у меня были данные, но у меня их нет.Все, что у меня есть, это веб-сайт , откуда можно отображать графики, но я не знаю, как получить данные оттуда.

Я провел сегодня день, пытаясь получить эти данные,включая запись в Google и использование программного обеспечения, которое отслеживает линию и выводит точки графика, такие как Datathief и DigitizeIt, но мне это не удалось.Я думаю, что последнее не сработало, потому что линии на графике слишком тонкие и имеют более одного оттенка синего.Конечно, я пытался улучшить качество изображения с помощью Paint и Gimp, но все еще не мог заставить его работать.

Я также пытался использовать eps2pgf, скрипт Java, который преобразует рисунки eps в код pgf, но даже этоне работал для графиков, которые я сохранил, используя Image Capture (Mac) и Print Screen (Windows), и, честно говоря, это был бы мой последний вариант, так как это "грубая сила", плевать уродливый код, который вы не можетедействительно улучшается.

После всего, что я решил начать изучать Python, потому что мой руководитель, человек, который попросил меня нарисовать эту картинку, используя tikz, сказал, что есть код Python для получения данных с таких сайтов, как этот,Теперь я даже не уверен, что Python справится с этой задачей (хотя я рад, что у меня есть повод для его изучения), и, конечно, требуется время, чтобы выучить новый язык и сделать что-то подобное, поэтому я хочу знать, действительно ли существуетспособ получить данные с этого сайта, используя предпочтительно Python, но если нет, любой другой метод.

1 Ответ

20 голосов
/ 07 мая 2011

Хорошо, было бы здорово, если бы Google предоставил API для этих данных! Тем не менее, вы все еще можете очистить некоторые данные с сайта. Вот как это сделать ...

Установить Firebug

Я предпочитаю Firebug для Firefox, но инструменты разработчика Chrome также должны работать.

Исследовать Перво-наперво, давайте перейдем к рассматриваемому url и воспользуемся Firebug, попробуем посмотреть, что происходит. Активируйте Firebug с помощью F12 или зайдите в Инструменты-> Firebug-> Открыть Firebug. Сначала нажмите на вкладку Net и перезагрузите страницу. Это показывает все сделанные запросы и даст вам некоторое представление о том, как работает сайт. Обычно плагины Flash загружают данные извне, а не вставляют их в реальный плагин, и если вы посмотрите на запросы, вы увидите запрос, помеченный POST service. Если вы наведите курсор мыши на него, firebug покажет полный URL, и вы увидите, что страница отправила запрос http://www.google.com/transparencyreport/traffic/service. Вы можете щелкнуть запрос и просмотреть отправленные заголовки, данные публикации, ответ и файлы cookie, использованные для выполнения запроса.

Request detail

Если вы посмотрите на ответ, вы увидите, что выглядит неправильно сформированным JSON. Из того, что я могу сказать, по-видимому, содержится список точек нормализованного трафика. На самом деле вы можете вырезать и вставить ответ из firebug, но так как это вопрос Python, давайте работать немного усерднее.

Получение данных в Python

Чтобы успешно выполнить запрос на публикацию, нам нужно сделать (почти) все, что делает браузер. Мы можем немного обмануть и просто скопировать заголовки запросов и опубликовать данные из firebug, чтобы подделать real запрос.

Заголовки и почтовые данные

Используйте тройные кавычки для вставки многострочных строк в оболочку. Скопируйте заголовки запроса и вставьте их. Request Headers

>>> headers = """ <paste headers> """

Затем преобразуйте его в dict для httplib2. Я собираюсь использовать понимание списка (которое разбивает строку на основе новых строк, а затем разбивает строку на первую: и удаляет завершающий пробел, что дает мне список списков из двух элементов, которые dict может преобразовать в словарь ), но вы можете сделать это, как хотите. Вы также можете вручную создать диктовку, я нахожу это быстрее.

>>> headers = dict([[s.strip() for s in line.split(':', 1)]
                               for line in headers.strip().split('\n')])

И скопируйте в сообщение данные. Copy post data used for the chart we are interested in

>>> body = """ <paste post data> """

Сделать запрос Я собираюсь использовать httplib2 , но есть несколько других http-клиентов и несколько хороших инструментов для очистки сети, таких как mechanize и scrapy . Мы сделаем запрос POST, используя URL к API, скопированные заголовки и данные поста, скопированные из firebug. Запрос возвращает кортеж заголовков и содержимого ответа.

>>> import httplib2 
>>> h = httplib2.Http()
>>> url = 'http://www.google.com/transparencyreport/traffic/service'
>>> resp, content = h.request(url, 'POST', body=body, headers=headers)

Данные массажа

Оригинальный формат действительно странный, и кажется, что только верхний бит содержит точки данных, поэтому я оставлю все остальное.

>>> cleaned = content.split("'")[0][4:-1] + ']' 

Теперь, когда это действительный JSON, мы можем десериализовать его в нативные типы данных Python.

>>> import json
>>> data = json.loads(cleaned)

Все точки, которые меня интересуют, являются числами с плавающей точкой, поэтому я буду фильтровать по ним.

>>> data = [x for x in data if type(x) == float]

Обработка / сохранение данных

Теперь, когда у нас есть наши данные, проверяем их, выполняем дополнительную обработку и т. Д. *

>>> data[:5] 
<<< 
[44.73874282836914,
 45.4061279296875,
 47.5350456237793,
 44.56114196777344,
 46.08817672729492]

... или просто сохраните его.

>>> with open('data.json', 'w') as f:
...:     f.write(json.dumps(data))

Мы могли бы также построить его, используя pyplot из matplotlib (или какую-либо другую библиотеку для построения графиков / графиков).

>>> import matplotlib.pyplot as plt
>>> plt.plot(data)

Pyplot

Заключение

Если вас просто интересует несколько вещей, вы можете настроить график так, чтобы отображать то, что вам нужно, а затем использовать заголовки запроса / данные публикации, используемые соответствующим запросом, до http://www.google.com/transparencyreport/traffic/service. Возможно, вы захотите проверить фактический ответ ближе, чем я, я просто отбросил части, которые не имели смысла для меня. Надеюсь, они предоставят открытый API для этих данных.

...