У меня есть много выражений xpath, хранящихся в базе данных, которые, я верю, верны. Проблема, с которой я столкнулся, заключается в том, что без их изменения я не могу получить правильные результаты при попытке получить путь к элементам с помощью lxml. Вот код Python:
def get_elements(response, xpath):
# Scrapy SelectorList
elements = response.xpath(xpath)
if not elements:
return []
result = []
tree = elements[0].root.getroottree()
for element in elements:
result.append(tree.getpath(element.root))
return result
Например, это выражение xpath
`//div[contains(@class, 'class')]//h3//a/@href`
работает нормально, и я могу получить значение, но не путь к элементу.
В этой строке
tree = elements[0].root.getroottree()
возникает ошибка
str объект не имеет атрибута getroottree
Если я удалю последний /@href
в выражении, он получит путь к элементу.
Для других выражений, таких как
//div[contains(@class, 'class')]//h3//a/@href|//div[contains(@class, 'another_class')]//h2//a/@href
или
//h3//a/text()|//strong[contains(@class, 'title')]//a/text()
Мне нужно удалить все /@href
и/text()
чтобы получить результаты.
Сейчас я изменяю xpath следующим образом, чтобы получить правильные элементы:
element_path = "|".join(
"/".join(r for r in s.split("/") if not (r.startswith('@') or r.endswith('()'))) for s in xpath.split("|")
)
Но в базе данных много выражений, таких как
.//div[contains(concat(' ', normalize-space(./@class), ' '), ' bref_list ')]//a/@href
, который будет неправильным после изменения
.//div[contains(concat(' ', normalize-space(.//h2[contains(concat(' ', normalize-space(.//a
и возникновения ошибки Invalid Xpath, или как это
.//article[contains(concat(' ', normalize-space(./@class), ' '), ' post-11508 ')]//span[contains(concat(' ', normalize-space(./@class), ' '), ' posted-on ')] | .//article[(contains(concat(' ', normalize-space(./@class), ' '), ' post ') and (position() >= 3) and (((position() - 3) mod 1) = 0))]//time[contains(concat(' ', normalize-space(./@class), ' '), ' entry-date ')]/text()
ТакЕсть ли какие-то основные правила или что-то вроде того, что я мог бы использовать или как я должен изменить выражения xpath, чтобы они работали?
PS: я не могу изменить выражения в базе данных напрямую.