右侧
国内最专业的黑客技术博客
当前位置:网站首页 > 黑客教程 > 正文

python定位元素_python定位标签

作者:hacker发布时间:2022-11-20分类:黑客教程浏览:374评论:3


导读:目录:1、python使用xpath(超详细)2、Python怎样获取XPath下的A标签的内容3、python爬虫怎么定位到这个标签?4、PythonPan...

目录:

python使用xpath(超详细)

使用时先安装 lxml 包

开始使用 #

和beautifulsoup类似,首先我们需要得到一个文档树

把文本转换成一个文档树对象

from lxml import etreeif __name__ == '__main__':doc='''

把文件转换成一个文档树对象

fromlxmlimportetree# 读取外部文件 index.htmlhtml = etree.parse('./index.html')result = etree.tostring(html, pretty_print=True)#pretty_print=True 会格式化输出print(result)

均会打印出文档内容

节点、元素、属性、内容 #

xpath 的思想是通过 路径表达 去寻找节点。节点包括元素,属性,和内容

元素举例

html ---...div ---

这里我们可以看到,这里的元素和html中的标签一个意思。单独的元素是无法表达一个路径的,所以单独的元素不能独立使用

路径表达式 #

/  根节点,节点分隔符,//  任意位置.  当前节点..  父级节点@  属性

通配符 #

*  任意元素@*  任意属性node()  任意子节点(元素,属性,内容)

谓语 #

使用中括号来限定元素,称为谓语

//a[n] n为大于零的整数,代表子元素排在第n个位置的 元素//a[last()]  last()  代表子元素排在最后个位置的 元素//a[last()-]  和上面同理,代表倒数第二个//a[position()3] 位置序号小于3,也就是前两个,这里我们可以看出xpath中的序列是从1开始//a[@href]    拥有href的 元素//a[@href='']    href属性值为''的 元素//book[@price2]  price值大于2的元素

多个路径 #

用| 连接两个表达式,可以进行 或匹配

//book/title | //book/price

函数 #

xpath内置很多函数。更多函数查看

contains(string1,string2)

starts-with(string1,string2)

ends-with(string1,string2) #不支持

upper-case(string) #不支持

text()

last()

position()

node()

可以看到last()也是个函数,在前面我们在谓语中已经提到过了

案例 #

定位元素 #

匹配多个元素,返回列表

fromlxmlimportetreeif__name__ =='__main__':doc='''

【结果为】

[Element li at 0x2b41b749848, Element li at 0x2b41b749808, Element li at 0x2b41b749908, Element li at 0x2b41b749948, Element li at 0x2b41b749988][]  #没找到p元素

html = etree.HTML(doc)print(etree.tostring(html.xpath("//li[@class='c2a0-a49b-d0c3-f32d item-inactive']")[0]))print(html.xpath("//li[@class='a49b-d0c3-f32d-ece3 item-inactive']")[0].text)print(html.xpath("//li[@class='d0c3-f32d-ece3-015f item-inactive']/a")[0].text)print(html.xpath("//li[@class='f32d-ece3-015f-714f item-inactive']/a/text()"))print(html.xpath("//li[@class='ece3-015f-714f-951e item-inactive']/.."))print(html.xpath("//li[@class='015f-714f-951e-911e item-inactive']/../li[@class='714f-951e-911e-ce83 item-0']"))

【结果为】

b' third item \n                'None    #因为第三个li下面没有直接text,Nonethird item  #['third item'][Element ul at 0x19cd8c4c848][Element li at 0x15ea3c5b848, Element li at 0x15ea3c5b6c8]

使用函数 #

contains #

有的时候,class作为选择条件的时候不合适@class='16af-3958-f183-ff0a ....' 这个是完全匹配,当王爷样式发生变化时,class或许会增加或减少像active的class。用contains就能很方便

from lxml import etreeif __name__ == '__main__':doc='''

【结果为】

[Element p at 0x23f4a9d12c8, Element li at 0x23f4a9d13c8, Element li at 0x23f4a9d1408, Element li at 0x23f4a9d1448, Element li at 0x23f4a9d1488]

starts-with #

from lxml import etreeif __name__ == '__main__':doc='''

【结果为】

[Element ul at 0x23384e51148, Element p at 0x23384e51248, Element li at 0x23384e51288, Element li at 0x23384e512c8, Element li at 0x23384e51308, Element li at 0x23384e51388][Element ul at 0x23384e51148]

ends-with #

print(html.xpath("//*[ends-with(@class,'ul')]"))

【结果为】

Traceback (most recent call last):File"F:/OneDrive/pprojects/shoes-show-spider/test/xp5_test.py",line18,inprint(html.xpath("//*[ends-with(@class,'ul')]"))File"src\lxml\etree.pyx",line1582,inlxml.etree._Element.xpathFile"src\lxml\xpath.pxi",line305,inlxml.etree.XPathElementEvaluator.__call__File"src\lxml\xpath.pxi",line225,inlxml.etree._XPathEvaluatorBase._handle_resultlxml.etree.XPathEvalError: Unregisteredfunction

看来python的lxml并不支持有的xpath函数列表

upper-case #

和ends-with函数一样,也不支持。同样报错lxml.etree.XPathEvalError: Unregistered function

print(html.xpath("//a[contains(upper-case(@class),'ITEM-INACTIVE')]"))

text、last #

#最后一个li被限定了print(html.xpath("//li[last()]/a/text()"))#会得到所有的`a`元素的内容,因为每个a标签都是各自父元素的最后一个元素。#本来每个li就只有一个a子元素,所以都是最后一个print(html.xpath("//li/a[last()]/text()"))print(html.xpath("//li/a[contains(text(),'third')]"))

【结果为】

['fifth item']['second item', 'third item', 'fourth item', 'fifth item'][Element a at 0x26ab7bd1308]

position #

print(html.xpath("//li[position()=2]/a/text()"))#结果为['third item']

上面这个例子我们之前以及讲解过了

* 这里有个疑问,就是position()函数能不能像text()那样用呢

print(html.xpath("//li[last()]/a/position()"))#结果  lxml.etree.XPathEvalError: Unregisteredfunction

这里我们得到一个结论,函数不是随意放在哪里都能得到自己想要的结果

node #

返回所有子节点,不管这个子节点是什么类型(熟悉,元素,内容)

print(html.xpath("//ul/li[@class='3958-f183-ff0a-95e5 item-inactive']/node()"))print(html.xpath("//ul/node()"))

【结果为】

[]['\n                ', , '\n                ', , '\n                ', , '\n                ', , '\n                ', , ' 闭合标签\n            ']

获取内容 #

**刚刚已经提到过,可以使用.text和text()的方式来获取元素的内容

from lxml import etreeif __name__ == '__main__':doc='''

【结果为】

['first item','second item','third item','fourth item','fifth item']first item18['\n                ','\n                ','\n                ','\n                ','\n                ',' 闭合标签\n            ']

看到这里,我们观察到text()和.text的区别。自己总结吧。不太好表达,就不表达了

获取属性 #

print(html.xpath("//a/@href"))print(html.xpath("//li/@class"))

【结果为】

['link1.html', 'link2.html', 'link3.html', 'link4.html', 'link5.html']['item-0active', 'item-1', 'item-inactive', 'item-1', 'item-0']

自定义函数 #

我们从使用函数的过程中得到结论,就是有的函数不支持,有的支持,那问题来了,到底那些方法支持呢。我们在lxml官网找到了答案。 。lxml 支持XPath 1.0 ,想使用其他扩展,使用libxml2,和libxslt的标准兼容的方式。 XPath 1.0官方文档  以及其他版本的XPath文档 

lxml supports XPath1.0, XSLT1.0andthe EXSLT extensions through libxml2andlibxsltina standards compliant way.

除此之外,lxml还提供了自定义函数的方式来扩展xpath的支持度 

from lxml import etree#定义函数def ends_with(context,s1,s2):return s1[0].endswith(s2)if __name__ == '__main__':doc='''

【结果为】

[Element li at 0x2816ed30548, Element li at 0x2816ed30508]['first item', 'third item']

形参s1会传入xpath中的第一个参数@class,但这里注意@class是个列表

形参s2会传入xpath中的第二个参数'active','active'是个字符串

官网例子

defhello(context, a):return"Hello %s"% afromlxmlimportetreens = etree.FunctionNamespace(None)ns['hello'] = helloroot = etree.XML('abHaegar/b/a')print(root.xpath("hello('Dr. Falken')"))# 结果为 Hello Dr. Falken

Python怎样获取XPath下的A标签的内容

1、在浏览器中打开网页。然后//div,就可以找到页面中的所有div了,因为//表示的是任意目录下查找。如图,页面有两个div,所以可以找到两个。

2、要查找类为a的div,可以在div后面用[@class="95e5-75aa-550c-4153 类名"]来指定,这样没有类名a的div就会被过滤掉,当然,还可以用id,把class改为[@id="id名"]即可。

3、用//,这样div下面的非a标签就会被跳过,直接去找a标签。

4、如果要获取a标签的href,那么可以获取到a标签后用/@href即可获得。

5、如果是获取文本的话,可以用text()这个方法,就会得到a标签里面的内容。

6、斜杠/表示的是获取子元素,比如div下面有两个子元素p,那么//div[2]/p获取的就是第二个div的子元素p。

python爬虫怎么定位到这个标签?

import requests

import re

re_text = requests.get(url).text

re_content = re.findall('meta name="keywords" content="(.*?)"/', re_text)

print(re_content)

.*? 表示非贪婪匹配,可以匹配到。

Python Pandas 依据标签或者位置选取特定行列 loc和iloc两种方式

Pandas中有两种方式可以进行特定行列的选取,一种是在知道每一列的名称(label)的情况下(df.loc),一种是在只知道列的位置(integer-location)的情况下(df.iloc)。

可以看出,上述的冒号(:)意味着选取所有的行,所以只需在此处进行改动即可选取特定行(前开后闭)

同样在选取特定行的时候,依然存在基于label或者是基于integer-location的选择

选取行采用df.iloc方式,具体如下

除此之外,在采用非标签的方式选择的时候,可以通过输入布尔型变量进行筛选,比如 df.iloc[[True, False, True]] ,或者是 df.iloc[lambda x: x.index % 2 == 0]

完结撒花,反正知道了df.loc和df.iloc的差别之后自由组合就好了~

参考资料:

标签:python定位标签


已有3位网友发表了看法:

  • 访客

    访客  评论于 2022-11-20 22:10:50  回复

    文档树 把文本转换成一个文档树对象 from lxml import etreeif __name__ == '__main__':doc='''把文件转换成一个文档树对象 fr

  • 访客

    访客  评论于 2022-11-20 21:53:03  回复

    单独的元素不能独立使用 路径表达式 # /  根节点,节点分隔符,//  任意位置.  当前节点..  父级节点@  属性 通配符 # *  任意元素@*  任意属性node

  • 访客

    访客  评论于 2022-11-21 01:05:34  回复

    tle | //book/price 函数 # xpath内置很多函数。更多函数查看 contains(string1,string2) starts-with(string1,string2) ends-with(string1,string2) #不支持 uppe

欢迎 发表评论:

黑客教程排行
最近发表
标签列表