Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 获取包含特定文本的xpath to标记_Python_Xpath_Beautifulsoup - Fatal编程技术网

Python 获取包含特定文本的xpath to标记

Python 获取包含特定文本的xpath to标记,python,xpath,beautifulsoup,Python,Xpath,Beautifulsoup,我试图找到网页上某些文本的xpath。如果要转到并尝试获取“EXERCISE”的xpath,它将类似于“html body html table tbody tr td div h4”。如果您进入该页面,右键单击“EXERCISE”并检查它,您可以看到代码底部的路径(在chrome中) 我尝试过许多途径。没有一个达到预期的效果。这是我得到的最接近的结果: soup = BS(page, 'html.parser') tags = [{"name":tag.name,"text":tag.text

我试图找到网页上某些文本的xpath。如果要转到并尝试获取“EXERCISE”的xpath,它将类似于“html body html table tbody tr td div h4”。如果您进入该页面,右键单击“EXERCISE”并检查它,您可以看到代码底部的路径(在chrome中)

我尝试过许多途径。没有一个达到预期的效果。这是我得到的最接近的结果:

soup = BS(page, 'html.parser')
tags = [{"name":tag.name,"text":tag.text,"attributes":tag.attributes} for tag in soup.find_all()]
s = ''
for t in tags:
    if "EXERCISE" in t['text']:
        s = s + t['name'] + " "
print(s)
开始时,我需要获取“html正文html表tbody tr td div h4”,但最终对于更复杂的页面,我还需要获取标记属性


谢谢

如果你知道你想要的标签总是有“EXERCISE”的确切文本(没有引号,或后面的不同情况,空格等),那么你可以在确切文本上使用
。find
。尽管您也可以使用正则表达式来代替,以防您确实想要检查空白变化以及其他情况

从那里,您可以利用
.parents
获得对象祖先的列表,即包含它的元素、包含该元素的元素,依此类推到文档顶部。然后只需提取标记名,反转列表,并将所有内容连接在一起

thetag = soup.find(string="EXERCISE")
parent_tags = [ p.name for p in list(thetag.parents) ]
print('/'.join(parent_tags[::-1]))
输出:

[文件]/html/body/hmtl/table/tr/td/div/h4

如果您不想在开始时使用“
[document]
”,可以通过多种方式将其取出,例如使用以下几行,而不是最后两行:

parent_tags = [ p.name for p in list(thetag.parents)[:-1] ]
print('/' + '/'.join(parent_tags[::-1]))
输出:

/html/body/hmtl/table/tr/td/div/h4


CSS选择器
:contains(EXERCISE):not(:has(:contains(EXERCISE))
将选择包含字符串“EXERCISE”的最内层标记

然后我们使用方法
find_parents()
查找此标记的所有父项并打印它们的名称:

import requests
from bs4 import BeautifulSoup

url = 'https://www.york.ac.uk/teaching/cws/wws/webpage1.html'

soup = BeautifulSoup(requests.get(url).text, 'html.parser')

t = soup.select_one(':contains(EXERCISE):not(:has(:contains(EXERCISE)))')
# you can use also this:
# t = soup.find(text="EXERCISE").find_parent()    

#lets print the path
tag_names = [t.name, *[t.name for t in t.find_parents()]]
print(' > '.join(tag_names[::-1]))
印刷品:

[document] > hmtl > body > table > tr > td > div > p > p > p > p > h4
使用lxml:

url = 'https://www.york.ac.uk/teaching/cws/wws/webpage1.html'

import requests
from lxml import etree
parser = etree.HTMLParser()
page  = requests.get(url,headers={"User-Agent":"Mozilla/5.0"})

root = etree.fromstring(page.content,parser)

tree = etree.ElementTree(root)
e = root.xpath('.//*[text()="EXERCISE"]')
print(tree.getpath(e[0]))
输出:

/html/body/hmtl/table/tr/td/div[2]/h4


您没有使用xpath来定位元素。这就是我的意图吗?没错,我正在使用精确的文本来定位元素,并希望返回它的路径。您标记了BeautifulSoup-您只需要xpath吗?它可以通过各种方式完成…使用CSS选择器,我真的很乐意使用任何方式。我只需要找出一个路径,我可以返回到soup.select(),这样它就可以再次返回文本。我标记xpath的原因是因为我在我的一次尝试中使用了它。您可以使用lxml吗?谢谢,这很有意义,而且似乎非常有效。问题是,输出是
[document]/hmtl/body/table/tr/td/div/p/p/p/h4
,因此其中有p。它们在h4之前打开和关闭,所以h4实际上不在它们内部,如果这有意义的话?这很有帮助。最后,我使用了这个方法,分割输出,然后在每个输出之间循环执行soup.select()并获取属性。不错