ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Xpath CSS Selector

2021-03-19 19:34:29  阅读:494  来源: 互联网

标签:Xpath xpath lxml 标签 Selector html print div CSS


xpath 和 css selector 方式的内容提取介绍

1.定位元素

在目标网页中,找到相应的元素,右键检查元素,看到元素的代码信息,找到自己需要的,进行右击,这时候有两种方式可以获得标签的位置的具体描述方式:

  1. 使用 copy selector
  2. 使用 copy XPath

图示:

 

这两种复制的路径有什么区别(以tr为例)?

copy XPath复制出来的路径:

/html/body/section/section/section/article/table[1]/tbody/tr[1]

copy selector复制出来的:

body > section > section > section > article >

table.table.table-striped.table-top20 > tbody > tr:nth-child(1)

这两种不同的路径描述方式,使用copy selector复制出来的路径叫做 CSS Selector,使用copy XPath复制出来的叫做XPath。

总之:

  1. XPath的路径是按照:谁,在哪,第几个的选择方式
  2. CSS Selector是按照:谁,在哪,第几个,长啥样来选择

3.内容提取方式一Xpath语言

XPath (XML Path Language) 是一门在 XML 文档中查找信息的语言(并不是解析器!是一种语言格式),可用来在 XML 文档中对元素和属性进行遍历。

一般xpath要配合lxml解析器来使用。

XPath 使用路径表达式来选取 XML 文档中的节点或者节点集。

*表示通配符。匹配任意节点

@*匹配节点中的任何属性

使用“ | ”运算符,选取若干个路径。

注意:

/ 和 // 的区别: / 代表只获取直接子节点; //获取子孙节点。

一般// 用的比较多。

./表示当前节点下,//表示全网页。

XPath语法——选取节点:

 

路径表达式类似这种:

/html/body/div[4]/div[2]/div/div[2]/div[14]/a

或者

/html/body/div[@class=”content”] ,

其中第一个路径叫绝对路径,其中每个‘/’就是一个节点。

第二个路径中的[@class=”content”] 是为了在多个相同标签中定位到一个标签。

 

在浏览器里面怎么找到你要的内容对应的xpath路径呢?

使用方法:

f12审查元素进去,然后直接在你需要爬的网页上面,找到你想要提取的对应地点,然后点击copy,copy xpath。

 

复制出来的xpath语言是这样的:

//*[@id="app"]/div/div/div/dl/dd[1]/div/div/div[1]/p[2]

那么怎么知道复制出来的xpath正不正确呢?

推荐两个xpath的插件。

在Chrome或Firefox浏览器中,有这样两个关于xpath的插件。可以快速找到对应网页的xpath路径。

  1. Chrome插件 XPath Helper
  2. Firefox插件 XPath Checker

插件使用效果:

当然你也可以直接在这个地方输入,ctrl+F,然后输入:

 

最后要注意的就是:使用.xpath() 的时候,其返回值是一个列表list,取值时需要注意。

4.内容提取方式—Css Selector

BeautifulSoup解析网页后,开始提取需要的内容,常用:Css Selector的方式。

BeautifulSoup本身不支持XPath表达式,可以用Css Selector的方式。

BeautifulSoup库有三种方法来查找元素。

  1. findall() 查找所有节点
  2. find() 查找单个
  3. selsect() 根据css的选择器Selector来查找

现在推荐的,就是第三种方式,根据css的选择器Selector来查找。

复制出来的 CSS Selector路径是这样的:

#app > div > div.tags-panel > ul > li:nth-child(1) > ul > li:nth-child(2)

同样也可以在浏览器里面验证你的CSS Selector路径是否正确?

ctrl+F 然后搜索自动匹配一下,找对了就会高亮。

 

BeautifulSoup结合Css Selector的爬虫提取例子:

import requests

from bs4 import BeautifulSoup

 

url = 'https://maoyan.com/films'

headers = {

    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'

}

response = requests.get(url, headers=headers)

if response.status_code == 200:

    soup = BeautifulSoup(response.text, 'html.parser') #也可用lxml

 

    # 获取文本,由于select()方法获得是list类型,必须要先获取到确定的元素,才能确定文本内容

    a1 = soup.select('body > div.header > div > div.city-container > div.city-selected')[0].get_text()

    print('Selector方式获取文本内容:',a1)

    a2 = soup.select('.city-name')[0].get_text()  # 按照标签名,id名,类名查找

    print('按标签名,id名,类名查询:',a2)

    a3 = soup.select('div .js-geo-city')  # 组合查找名为jsxxx的div。用空格分开

    print('组合查找:',a3)

   

# 查img的src,a标签中的href属性

    a4 = soup.select('div.movie-item > a > div > img:nth-of-type(2)')[0]['data-src']

    print('找img的src属性:',a4)

    # 重复li取其中一项:

    a5 = soup.select('div.channel-detail.channel-detail-orange')[0].get_text()

    print('重复li取其中一项:',a5)

 

    # 批量查询,比如table中多组td,div中多组li

    a6 = soup.select('body > div.header > div > div.nav > ul > li')

    for li in a6:

        # print(li)

        a = li.find('a')['href']

        # print(a)

        wz = li.text

        print('批量查找:',wz)

    # 与find方法对比-多但是copy快。

    a3111 = soup.find('div', class_='city-name').text

    print('与find方法对比:',a3111)

else:

    print('error', response.status_code)

常用的就是如下的了:

  1. 获取某个节点的文字:比如p标签外面的文字,标题
  2. 获取某个节点的属性值:比如a标签的href,img的src。
  3. 获取某个指定名称的点的文本内容或者属性:比如某个class='city-name’的div的内容。
  4. 批量获取列表型内容,比如table的多个td,div的多个li。

5.网页解析器lxml库

除了BeautifulSoup解析器以外,还有 lxml 也是python的一个解析库,而且解析效率非常高,支持HTML或XML的解析,支持使用Xpath1.0语法来解析代码。

主要的功能是如何解析和提取 HTML/XML 的数据。

注意:lxml和上面说的两种,xpath和css selector不是同一个类别。这是和BeautifulSoup一个级别的解析器。

使用 pip 安装:pip install lxml

代码使用的时候,主要是lxml的etree库来解析:

from lxml import etree 

利用lxml来 解析HTML代码,在解析HTML代码的时候,如果HTML代码不规范,他会自动的进行补全。

比如:

# 先安装lxml: pip install lxml

 

from lxml import etree  # 用lxml来解析HTML代码-自动补全

text='''

<div>

    <ul>

         <li class="item-0"><a href="link1.html">first item</a></li>....

'''

# 利用 etree.HTML 把字符串解析成 HTML 文件

html = etree.HTML(text)

# 按字符串序列化HTML文档

result = etree.tostring(html).decode()

print(result )

运行结果:

输出后,会补全了li标签,还添加了body,html标签。

 

因为lxml支持xpath,而且lxml快,xpath获得也非常方便,所以,我们

一般采用 “lxml+xpath” 的方式 来快速的定位特定元素以及节点信息。

( lxml+Selector也可以,但是推荐用xpath)

5.1 lxml 结合 xpath的常用方式:

使用xpath语法。应该使用Element.xpath方法。来执行xpath的选择。

示例代码如下:

 trs = html.xpath("//tr[position()>1]")

xpath函数 返回来的永远是一个列表。

获取某个标签的属性:

href = html.xpath("//a/@href") # 获取a标签的href值

获取文本,是通过xpath中的text()函数。

示例代码如下:

address = tr.xpath("./td[4]/text()")[0]

在某个标签下,再执行xpath函数,获取这个标签下的子孙元素,那么应该在斜杠之前加一个点,代表是在当前元素下获取。

示例代码如下:

  address = tr.xpath("./td[4]/text()")[0]

xpath解析器下元素下标从1开始。

5.2 根据读取的对象不同—方式也不同:

1.修正HTML代码,补齐标签

from lxml import etree

html=etree.HTML(text) #Lxml库解析数据,为Element对象

result=etree.tostring(html) #此时可以自动修正HTML代码,补齐标签等等

2.读取本地的HTML文件

读取本地的HTML文件使用parse()方法

from lxml import etree

html=etree.parse(r"文件路径")

result=etree.tostring(html,pretty_print=True)

3.解析在线请求回来的HTML源码

使用requests获取HTML源码后,

html=etree.HTML(res.text)

result = etree.tostring(html).decode() #实现对其的解析

再次提醒:使用.xpath() 的时候,其返回值是一个列表list

5.3 lxml和xpath 爬虫的提取例子:

# xpath函数返回的是一个列表

str ="""

    <div class="wrapper">

        <i class="iconfont icon-back" id="back">马麻花</i>

        <a href="/" id="channel">新浪社会</a>

        <ul id="nav">

            <li><a href="http://domestic.firefox.sina.com/" title="国内">国内</a></li>

            <li><a href="http://world.firefox.sina.com/" title="国际">国际</a></li>

            <li><a href="http://mil.firefox.sina.com/" title="军事">军事</a></li>

            <li><a href="http://photo.firefox.sina.com/" title="图片">图片</a></li>

            <li><a href="http://society.firefox.sina.com/" title="社会">社会</a></li>

            <li><a href="http://ent.firefox.sina.com/" title="娱乐">娱乐</a></li>

            <li><a href="http://tech.firefox.sina.com/" title="科技">科技</a></li>

            <li><a href="http://sports.firefox.sina.com/" title="体育">体育</a></li>

            <li><a href="http://finance.firefox.sina.com/" title="财经">财经</a></li>

            <li><a href="http://auto.firefox.sina.com/" title="汽车">汽车</a></li>

        </ul>

        <i class="iconfont icon-liebiao" id="menu">张三丰</i>

    </div>

    """

 

from lxml import etree

 

html=etree.HTML(str)        #创建一个html对象

result1=html.xpath("//a/text()")    #获取所有a标签下的所有内容

print(result1)

result2=html.xpath("//a/@href")    #获取所有a标签下的所有内容

print(result2)

result3=html.xpath("//li/a/text()") #获取标签下的内容

print(result3)

result4=html.xpath('//a[@id="channel"]/text()') #获取带属性的标签的内容

print(result4)

result5=html.xpath("//li[position()<4]/a/text()") #选前三项

print(result5)

result6=html.xpath("//li[1]/a/text()")      #第一个

print(result6)

result7=html.xpath("//li[last()]/a/text()")      #最后一个last()-1倒数第二项

print(result7)

result8=html.xpath("//i[contains(@class,'iconfont')]/text()")   #class类中包含iconfont的取出来

print(result8)

效果:

 

补充几种常见情况:

遇到相同的字符开头的多个标签?

<li class="tag-1">需要的内容1</li>

<li class="tag-2">需要的内容2</li>

<li class="tag-3">需要的内容3</li>

想同时爬取时,不需要构造多个Xpath路径,通过 starts-with()便可以获取多个标签内容。

starts-with()如下:

contents = selector.xpath('//li[starts-with(@class,"tag")]/text() ')

当遇到标签套标签情况时,想同时获取文本内容:

<div class="red">需要的内容1

<h1>需要的内容2</h1>

</div>>

可以使用string(.)方法如下:

from lxml import etree

 

html2 = '''

<div class="red">需要的内容1

<h1>需要的内容2</h1>

</div>>

'''

 

selector = etree.HTML(html2)

content1 = selector.xpath('//div[@class="red"]')[0]

content2 = content1.xpath('string(.)')

print(content2)

string(.)方法可用于标签套标签情况。

总结:

  1. xpath 和 css selector 是同一类,都是用来定位元素的两种不同的路径。其中xpath比css selector更高效一些。BeautifulSoup和Lxml是同一类,都是解析网页的解析器。
  2. 对于网页解析器BeautifulSoup,它本身不支持XPath表达式,所以可以用Css Selector的方式。
  3. 对于网页解析器Lxml,它支持xpath表达式,也支持Css Selector的方式,推荐使用xpath的方式。

最后说两句:

lxml只支持xpath1.0,不支持xpath2.0,Xpath2.0支持正则匹配,而1.0不支持,但是目前很多功能用不到。(但是,我还真没找到关于XPATH 2.0的教程或项目实例。截止2019/11月。现在市面上的网页基本上都还是xpath1的。)

其他参考网站:

https://www.cnblogs.com/jjb1997/p/11234638.html

https://www.jianshu.com/p/1660003f40c8

https://www.cnblogs.com/yiyea/p/11446981.html

https://www.cnblogs.com/wsg-python/articles/10182177.html

https://www.cnblogs.com/liudi2017/articles/9158390.html

https://www.cnblogs.com/zhangxinqi/p/9210211.html#_label16

标签:Xpath,xpath,lxml,标签,Selector,html,print,div,CSS
来源: https://blog.csdn.net/weixin_43955170/article/details/115014010

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有