Python и xpath: идентифицируйте HTML-теги с разнесенными атрибутами - PullRequest
0 голосов
/ 25 июня 2018

Учитывая следующий код:

<div class="tag1">
<div>
    <a class="tag11 tag12" href="http://www.example.com/file1" title="file1"><img class="tag2" src="http://www.example.com/img1.jpg" alt="textalt">linktext</a>
    <span class="tag3">.</span>
</div>

<div>
    <a class="tag11 tag12" href="http://www.example.com/file2" title="file2"><img class="tag2" src="http://www.example.com/img1.jpg" alt="textalt">linktext</a>
    <span class="tag3">.</span>
</div>

Это часть большей HTML-страницы, которая содержит другие a элементы с другими тегами. Однако я хотел бы сослаться only на элементы a, класс которых tag11 tag12, и создать список, содержащий все их значения href. Между tag11 и tag12 есть пробел.

Используя Python 3.5, lxml и xpath, вот первая попытка:

from lxml import html
import requests

page = requests.get('http://www.example.com/page.html')
tree = html.fromstring(page.content)

atest = tree.xpath('//a[contains(@class='tag11 tag12')]')

но это не работает. Использование отдельных вершин:

File "<stdin>", line 1
    buyers = tree.xpath('//a[contains(@class='tag11 tag12')]')
                                                  ^
SyntaxError: invalid syntax

Использование двойных вершин:

tree.xpath('//a[contains(@class="tag11 tag12")]')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "src/lxml/lxml.etree.pyx", line 1587, in lxml.etree._Element.xpath (src/lxml/lxml.etree.c:61854)
  File "src/lxml/xpath.pxi", line 307, in lxml.etree.XPathElementEvaluator.__call__ (src/lxml/lxml.etree.c:178516)
  File "src/lxml/xpath.pxi", line 227, in lxml.etree._XPathEvaluatorBase._handle_result (src/lxml/lxml.etree.c:177421)
lxml.etree.XPathEvalError: Invalid number of arguments

Также (из этот ответ ):

atest = tree.xpath('//a[contains(@class, "tag11") and contains(@class, "tag12")]')

получен пустой список atest.

Как правильно обрабатывать a элементы, чей тег class содержит пробелы?


Я использую Python 3.5, lxml и xpath, потому что я пытаюсь изучить эти инструменты. Таким образом, нет особой причины не использовать BeautifulSoup, но я просто ищу конкретное решение для этих перечисленных инструментов, если таковые имеются.

Ответы [ 3 ]

0 голосов
/ 25 июня 2018

Проверьте этот XPath: '//a[@class="tag11 tag12"]/@href '

from lxml import html

page = "<div class=\"tag1\"> <div> <a class=\"tag11 tag12\" href=\"http://www.example.com/file1\" title=\"file1\"><img class=\"tag2\" src=\"http://www.example.com/img1.jpg\" alt=\"textalt\">linktext</a> <span class=\"tag3\">.</span> </div> <div> <a class=\"tag11 tag12\" href=\"http://www.example.com/file2\" title=\"file2\"><img class=\"tag2\" src=\"http://www.example.com/img1.jpg\" alt=\"textalt\">linktext</a> <span class=\"tag3\">.</span> </div>"
tree = html.fromstring(page)
links = tree.xpath('//a[@class="tag11 tag12"]/@href')

for link in links:
    print(link)

Вывод:

http://www.example.com/file1
http://www.example.com/file2
0 голосов
/ 25 июня 2018

Попробуйте следующий подход для игры с несколькими классами.Он вернет требуемый вывод, если присутствуют оба из classes:

from lxml.html import fromstring

content = """
<div class="tag1">
<div>
    <a class="tag11 tag12" href="http://www.example.com/file1" title="file1"><img class="tag2" src="http://www.example.com/img1.jpg" alt="textalt">linktext</a>
    <span class="tag3">.</span>
</div>

<div>
    <a class="tag11 tag12" href="http://www.example.com/file2" title="file2"><img class="tag2" src="http://www.example.com/img1.jpg" alt="textalt">linktext</a>
    <span class="tag3">.</span>
</div>
"""
tree = fromstring(content)
for atest in tree.xpath('//a[contains(@class, "tag11") and contains(@class, "tag12")]'):
    print(atest.attrib['href'])

Выход:

http://www.example.com/file1
http://www.example.com/file2
0 голосов
/ 25 июня 2018

Есть ли причина не использовать BeautifulSoup4? Вот фрагмент кода из моего проекта:

import urllib.request             # You could use requests library as well   
from bs4 import BeautifulSoup

url = 'http://www.example.com/page.html'
header = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
         "AppleWebKit/537.36 (KHTML, like Gecko)"
         "Chrome/67.0.3396.87 Safari/537.36"}

soup = BeautifulSoup(urllib.request.urlopen(
                     urllib.request.Request(url, headers=header)),
                     'lxml')

links = list()
for link in soup.find_all('a', class_='tag1 tag2'):
    links.append(link.get('href'))
...