2010-12-01 2 views
5

Я использую lxml в Python для анализа некоторого HTML, и я хочу извлечь всю ссылку на изображения. Как я сделать это прямо сейчас:Python, XPath: Найти все ссылки на изображения

//a[contains(@href,'.jpg') or contains(@href,'.jpeg') or ... (etc)] 

Есть несколько проблем с этим подходом:

  • вы должны перечислить все возможные расширения изображения во всех случаях (как «JPG» и " JPG "), которым не элегантный
  • в странной ситуации, то HREF может содержать .jpg где-то в середине, а не в конце строки

Я хотел использовать регулярное выражение, но мне не удалось:

//a[regx:match(@href,'.*\.(?:png|jpg|jpeg)')] 

Возвращаемый мне все ссылки все время ...

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

+0

Хороший вопрос, +1. См. Мой ответ для решения одной из ваших проблем - поиск @href, который заканчивается только заданной строкой. – 2010-12-01 21:46:31

+0

В дополнение к другим ответам, описывающим подстроки, вы можете использовать функцию перевода для грубого преобразования case. translate (@href, "EGIJFNP", "egijfnp") (все символы в png, jpeg, gif). – yonran 2010-12-02 01:53:24

ответ

2

Вместо:

a[contains(@href,'.jpg')] 

Применение:

a[substring(@href, string-length(@href)-3)='.jpg'] 

(и тот же паттерн экспрессии для других возможных окончаний).

выше выражение является XPath 1.0 эквивалентно следующему XPath 2.0 выражения:

a[ends-with(@href, '.jpg')] 
2

Используйте XPath для возврата всех элементов <a> и используйте понимание списка Python для фильтрации до тех, которые соответствуют вашему регулярному выражению.

1

Потому что нет гарантии, что ссылка имеет расширение файла вообще или что расширение файла даже соответствует содержимому (.jpg URL-адреса, возвращающим ошибку HTML, например), что ограничивает ваши параметры.

Единственный правильный способ собрать все изображения с сайта - получить каждую ссылку и запросить его с запросом HTTP HEAD, чтобы узнать, какой тип содержимого он отправляет для этого. Если тип содержимого - это изображение/(что-либо), это изображение, иначе это не так.

Скремблирование URL-адресов для общих расширений файлов, вероятно, приведет к вам 99,9% изображений. Это не изящно, но и не самый HTML. Я рекомендую быть счастливым поселиться на 99,9% в этом случае. Дополнительные 0,1% не стоят того.

0

Использование:

//a[@href[contains('|png|jpg|jpeg|', 
        concat('|', 
          substring-after(substring(.,string-legth()-4),'.'), 
          '|')]] 
2

lxml поддерживает регулярные выражения в EXSLT пространстве имен:

from lxml import html 

# download & parse web page 
doc = html.parse('http://apod.nasa.gov/apod/astropix.html') 

# find the first <a href that ends with .png or .jpg or .jpeg ignoring case 
ns = {'re': "http://exslt.org/regular-expressions"} 
img_url = doc.xpath(r"//a[re:test(@href, '\.(?:png|jpg|jpeg)', 'i')]/@href", 
        namespaces=ns, smart_strings=False)[0] 
print(img_url) 
Смежные вопросы