【问题标题】:lxml - Finding all links with certain extensionslxml - 查找具有特定扩展名的所有链接
【发布时间】:2013-12-11 19:23:07
【问题描述】:

我正在尝试使用 lxml 从锚链接中查找所有图像(.png、.bmp、.jpg)和可执行文件 (.exe)。从这个similar thread,接受的答案建议做这样的事情:

png = tree.xpath("//div/ul/li//a[ends-with(@href, '.png')]")
bmp = tree.xpath("//div/ul/li//a[ends-with(@href, '.bmp')]")
jpg = tree.xpath("//div/ul/li//a[ends-with(@href, '.jpg')]")
exe = tree.xpath("//div/ul/li//a[ends-with(@href, '.exe')]")

但是,我不断收到此错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "lxml.etree.pyx", line 2095, in lxml.etree._ElementTree.xpath (src/lxml/lxml.etree.c:53597)
  File "xpath.pxi", line 373, in lxml.etree.XPathDocumentEvaluator.__call__ (src/lxml/lxml.etree.c:134052)
  File "xpath.pxi", line 241, in lxml.etree._XPathEvaluatorBase._handle_result (src/lxml/lxml.etree.c:132625)
  File "xpath.pxi", line 226, in lxml.etree._XPathEvaluatorBase._raise_eval_error (src/lxml/lxml.etree.c:132453)
lxml.etree.XPathEvalError: Unregistered function

我正在通过 pip 运行 lxml 3.2.4。

另外,不是为每个文件扩展名定义 4 次 xpath,有没有办法使用 xpath 并一次指定所有四个文件扩展名?

【问题讨论】:

    标签: python html lxml web-crawler


    【解决方案1】:

    ends-with 是为 XPath 2.0、XQuery 1.0 和 XSLT 2.0 定义的函数,而 lxml 仅支持 XPath 1.0、XSLT 1.0 和 EXSLT 扩展。所以你不能使用这个功能。文档是herehere

    您可以在 XPATH 中使用正则表达式。以下是返回与正则表达式匹配的节点的示例代码:

    regexpNS = 'http://exslt.org/regular-expressions'
    tree.xpath("//a[re:test(@href, '(png|bmp|jpg|exe)$')]", namespaces={'re':regexpNS}")
    

    这里有一个类似的问题Python, XPath: Find all links to imagesregular-expressions-in-xpath

    【讨论】:

      【解决方案2】:

      我认为这是一个外部库无法识别ends-with 函数的问题。 documentation discusses working with links。我认为更好的解决方案是:

      from urlparse import urlparse
      tree.make_links_absolute(base_href='http://example.com/')
      links = []
      for i in tree.iterlinks():
          url = urlparse(i[2])  # ensures you are getting the remote file path
          if url.path.endswith('.png') or url.path.endswith('.exe') ... :
              # there are other ways you could filter the links here
              links.append(i[2])
      

      【讨论】:

      • 如果我知道链接的位置(即在无序列表"//div/ul/li//a" 中),有没有办法让iterlinks() 只搜索无序列表而不是整个dom?
      • 嗯.. 当我执行tree.iterlinks() 时,我收到此错误:AttributeError: 'lxml.etree._ElementTree' object has no attribute 'iterlinks'.
      猜你喜欢
      • 2011-05-03
      • 2012-01-26
      • 2011-08-21
      • 2019-07-21
      • 2010-09-06
      • 2019-06-14
      • 1970-01-01
      • 2011-03-13
      相关资源
      最近更新 更多