Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
contains(@style, 'width: 100%')//div[@id="data"]//td[contains(text(), "Цена")]/../td[2]/text() selector = HtmlXPathSelector(response)
selector.select(".//table[@class='pricetable']/tr[1]/td[2]/text()").re("(\d+)\s*([^0-9 ]+)")
contact_email = safe_list_get(selector.select(".//table[@width='90']//script/text()").re('document.write\((.*)\)'), 0)
if contact_email:
contact_email = re.match("<a.*>(.*)</a>", common.eval_js(contact_email.encode("utf-8"), common.js_context)).group(1)
if contact_email and common.re_patterns["email"].match(contact_email):
contact["Email"] = contact_email
div[contains(@class,’productInfo’)]
from lxml import etree
def xpath_class_matches(context, *args):
"""XPath extension function. Return number of node class names matches.
<div class="c1 c2 c3 c4"/>
//div[class-matches('c1', 'c2, 'c5') == 2]
"""
class_attr = context.context_node.attrib.get("class", None)
matches = 0
if class_attr:
classes_ = class_attr.split(" ")
for class_ in classes_:
if class_ in args:
matches += 1
return matches
ns = etree.FunctionNamespace(None)
ns['class-matches'] = xpath_class_matches
tree = etree.HTML(html_string)
tree.xpath("//div[class-matches('productInfo')]")
div class="smth-productInfoSmth".div[@id=’productInfo’]//h1 — не знал, что так можно. Писал всегда descendant::h1.// или descendant:: оси заметно сказываются на производительности, хоть и очень удобные.не знал, что так можно. Писал всегда descendant::h1.
Любой нормальный движок XPath позволяет писать собственные функции.
Парсинг сайтов-магазинов. Личный опыт и немного how-to