我在Python中使用lxml来解析一些HTML,我想提取所有链接到图像。我现在这样做的方式是:
//a[contains(@href,'.jpg') or contains(@href,'.jpeg') or ... (etc)]
这种方法存在一些问题:
我想使用正则表达式,但我失败了:
//a[regx:match(@href,'.*\.(?:png|jpg|jpeg)')]
这一直让我回复了所有链接......
有没有人知道正确,优雅的方式来做这个或我的正则表达式方法有什么问题?
答案 0 :(得分:2)
使用XPath返回所有<a>
元素,并使用Python列表推导过滤到与正则表达式匹配的元素。
答案 1 :(得分: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 :(得分: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)
答案 3 :(得分:1)
因为无法保证链接完全具有文件扩展名,或者文件扩展名甚至与内容(例如返回错误HTML的.jpg网址)相匹配,这限制了您的选项。
从站点收集所有图像的唯一正确方法是获取每个链接,并使用HTTP HEAD请求查询它,以找出服务器为其发送的内容类型。如果内容类型是图像/(任何),那么它就是图像,否则就不是。
抓取常见文件扩展名的网址可能会让你获得99.9%的图片。它并不优雅,但大多数HTML都不是。我建议很高兴在这种情况下满足99.9%。额外的0.1%是不值得的。
答案 4 :(得分:0)
使用:
//a[@href[contains('|png|jpg|jpeg|',
concat('|',
substring-after(substring(.,string-legth()-4),'.'),
'|')]]