Wikipedia Философия игровой схемы в Python и R - PullRequest
5 голосов
/ 08 ноября 2011


Так что я относительно новичок в python, и для того, чтобы учиться, я начал писать программу, которая выходит в онлайн в Википедии, находит первую ссылку в разделе обзора случайной статьи, следует по этой ссылке и продолжает работать, пока она не войдет в Зацикливается или находит страницу философии (как подробно здесь ), а затем повторяет этот процесс для новой случайной статьи указанное количество раз. Затем я хочу собрать результаты в некоторой форме полезной структуры данных, чтобы я мог передать данные в R с помощью библиотеки Rpy , чтобы я мог нарисовать какую-то сетевую диаграмму (R довольно хорош в рисование подобных вещей), где каждый узел на диаграмме представляет посещенные страницы, а стрелки - пути, взятые из начальной статьи на страницу философии.

Так что у меня нет проблем с получением python для возврата достаточно структурированного html из вики, но есть некоторые проблемы, которые я не могу до конца понять. До сих пор я выбирал первую ссылку с помощью cssselector из библиотеки lxml. Он выбирает первую ссылку (в теге), которая является прямым потомком тега p, который является прямым потомком тега div с class = "mw-content-ltr", например так:

    user_agent = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT)'
    values = {'name' : 'David Kavanagh',
      'location' : 'Belfast',
      'language' : 'Python' }
    headers = { 'User-Agent' : user_agent }
    encodes = urllib.urlencode(values)
    req = urllib2.Request(url, encodes, headers)
    page = urllib2.urlopen(req)
    root = parse(page).getroot()
    return root.cssselect("div.mw-content-ltr>p>a")[0].get('href')

Этот код находится в функции, которую я использую, чтобы найти первую ссылку на странице. Это работает по большей части, но проблема в том, что если первая ссылка находится внутри какого-то другого тега, а не является прямым потомком тега p, как, скажем, тег b или что-то еще, то я пропускаю его. Как вы можете видеть из статьи вики выше, ссылки, выделенные курсивом или внутри скобок, не подходят для игры, что означает, что я никогда не получаю ссылку курсивом (хорошо), но часто получаю ссылки, которые заключены в скобки (плохо) и иногда пропускаю первую ссылку на странице, такую ​​как первая ссылка в статье Председателя, которая является стулом, но выделена жирным шрифтом, поэтому я не понимаю ее. Я попытался удалить условие прямого потомка, но затем я часто получаю ссылки, которые находятся «над» разделом обзора, которые обычно находятся в боковом блоке, в теге ap, в таблице, в том же элементе div, что и раздел обзора.

Итак, первая часть моего вопроса:

Как я могу использовать cssselectors или какую-то другую функцию или библиотеку, чтобы выбрать первую ссылку в разделе обзора, которая не находится в скобках или курсивом. Я думал об использовании регулярных выражений для просмотра необработанного HTML, но это кажется очень неуклюжим решением, и я подумал, что может быть что-то более приятное, о чем я даже не думал.

Так что в настоящее время я сохраняю результаты в списке списков. Итак, у меня есть список с названием paths, в котором есть списки, содержащие строки, содержащие заголовок статьи вики.

Вторая часть вопроса: Как я могу пройти этот список списков, чтобы представить несколько сходящихся путей? Сохранение результатов как это хорошая идея? Поскольку конечная диаграмма должна выглядеть как перевернутое дерево, я подумал о создании какого-то класса дерева, но это кажется большой работой для чего-то концептуального, довольно простого.

Любые идеи или предложения будут с благодарностью.
Cheers,
Дэви

Ответы [ 2 ]

4 голосов
/ 08 ноября 2011

Я просто отвечу на второй вопрос:

Для начала, просто держите дикт, отображающий одно название статьи в Википедии на другое.Это позволит легко и быстро проверить, есть ли у вас статья, которую вы уже нашли ранее.По сути, это просто хранение вершин ориентированного графа, проиндексированных по их происхождению.

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

РЕДАКТИРОВАТЬ

Хорошо, я также отвечу на первый вопрос...

Для первой части я настоятельно рекомендую использовать MediaWiki API вместо получения версии HTML и ее анализа.API позволяет запрашивать определенные типы ссылок, например, просто ссылки между вики или просто ссылки между языками.Кроме того, есть клиентские библиотеки Python для этого API, которые должны упростить его использование из кода Python.

Не разбирайте HTML-код веб-сайта, если он предоставляет всеобъемлющий и хорошо документированный API!

1 голос
/ 08 ноября 2011

Для первой части невозможно найти скобки с селекторами css, потому что для html скобки - это просто текст.

На вашем месте я бы использовал селекторы, чтобы найти всесоответствующие элементы абзаца, которые действительны для игры.Затем я посмотрел в тексте элемента абзаца и удалил все недопустимое, например, что-то в скобках и что-нибудь между тегами курсивом.Затем я бы искал в этом обработанном тексте нужные мне элементы ссылки.Это немного лучше, чем ручная обработка всего HTML-документа.

Я не уверен, что точно следую тому, что вы делаете для второй части, но для представления результатов этого поиска в виде дерева:плохая идея, поскольку вы ищете циклы, которые деревья не могут представить.

Для структуры данных у меня были бы списки «узлов», где узел представляет страницу и имеет URL-адрес и количество вхождений.Затем я бы использовал алгоритм грубой силы для сравнения списков узлов - если в двух списках есть одинаковые узлы, вы можете объединить их, увеличив число подсчетов для каждого зеркального узла.

Iне будет использовать стандартный список 'Python', поскольку это не может вернуться к самому себе.Возможно, создайте собственную реализацию связанного списка, содержащего узлы.

...