2015-10-16 3 views
0

Я загружаю и прокручиваю на динамически загружаемых страницах. Примером является «стена» Facebook, которая загружает только следующие предметы, как только вы прокручиваете их где-нибудь рядом с дном.Скребок и разбор с Python - lxml с длинными Xpaths

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

Я хотел бы извлечь определенные части веб-страницы. Я использовал lxml module в python, но с ограниченным успехом. На веб-сайте они показывают только примеры с довольно короткими Xpath.

Ниже приведен пример функции и путь, который дает мне имена пользователей, включенные на страницу.

usersID = elTree.xpath('//a[@class="account-group js-account-group js-action-profile js-user-profile-link js-nav"]') 

это работает довольно хорошо, но я получаю некоторые errors (еще один пост моего), такие как:

TypeError: 'NoneType' object has no attribute 'getitem' 

Я также смотрел на XPaths, что Firebug предоставляет. Это, конечно, намного дольше и очень специфично. Вот пример для reoccuring элемента на странице:

/html/body/div[2]/div[2]/div/div[2]/div[2]/div/div[2]/div/div/div/div/div[2]/ol[1]/li[26]/ol/li/div/div[2]/p 

Часть к концу li[26] показывает, что это 26-й пункт в списке того же элемента, которые находятся на том же уровне HTML дерева ,

Я хотел бы знать, как я могу использовать такие firebug-Xpaths с библиотекой lxml, или кто-нибудь знает, как лучше использовать Xpaths в целом?

Используя примеры кода HTML и инструменты like this для целей тестирования, Xpaths из Firebug вообще не работают. Этот путь просто смешон в опыте людей?

Is Очень специфичный для исходного кода? Существуют ли какие-либо другие инструменты, такие как Firebug, которые обеспечивают более надежный вывод для использования с lxml?

+0

«xpath()' python's lxml - это полный процессор запросов XPath 1.0. Таким образом, оба пути, которые вы показываете, разрешены. Ваша ошибка означает, что на этом конкретном пути нет значения - либо фактических данных, либо путей не существует. Использование '//' в xpath ссылается на точное абсолютное местоположение (т. Е. Ярлык), в то время как '/' требует полного пути относительно корневого узла. – Parfait

+0

Есть ли надежный способ использования регулярных выражений в Xpaths, например, добавление '*' для получения всех данных по пути или с определенного уровня? –

ответ

0

Я нашел две вещи, которые вместе работали очень хорошо для меня.

Первое:

Пакет LXML позволяет использовать некоторые функции в сочетании с Xpath. Я использовал функцию starts-with следующим образом:

tweetID = elTree.xpath("//div[starts-with(@class, 'the-non-varying-part-of-a-very-long-class-name')]") 

При изучении HTML код (дерево), используя такие инструменты, как Firebug/Firepath, все показано красиво и аккуратно - например:

*

Xpath and class name in Firebug

*

Когда я использовал выделенный путь, т.е. tweet original-tweet js-original-tweet js-stream-tweet js-actionable-tweet js-profile-popup-actionable has-cards has-native-media with-media-forward media-forward cards-forward - искать мою ELT в коде выше, ничего не найдено.

Имея взглянуть на фактический HTML-файл, который я пытался разобрать, я видел, что это было на самом деле распространяется на множество линий - как это:

Actual HTML code

это объясняет, почему пакет LXML не находил его согласно моему поиску.

Вторая вещь:

Я знаю, как правило, не рекомендуется, так как обходной путь, но подход Python, что «проще попросить прощения, чем разрешения» применяется в моем случае - следующий, что я сделал должен был использовать python try/except на TypeError, который я продолжал получать, по-видимому, в произвольных строках моего кода.

Это может быть специфично для моего кода, но после проверки вывода во многих случаях кажется, что он хорошо работает для меня.

1

FireBug фактически генерирует действительно бедные xpaths. Они длинные и хрупкие, потому что они невероятно неспецифичны вне иерархии. Страницы сегодня невероятно динамичны.

Лучший способ работы с xpath на динамических страницах - найти общие элементы в качестве крючка и выполнить xpath ops из них в качестве вашего корня пути. То, что я имею в виду под общим элементом, - это стабильные структурные элементы, которые очень вероятно или гарантированно присутствуют. Выберите ближайшую к вашей цели с точки зрения иерархии сдерживания. Более короткие пути быстрее и понятнее.

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

Высокодинамичные страницы требуют сложных и динамичных подходов.

Facebook сильно меняется и потребует частого обслуживания скриптов.

+0

Хороший совет, спасибо! У вас есть какие-либо знания/опыт в Twitter? –