美文网首页
Xpath,CSS选择器

Xpath,CSS选择器

作者: 蒲小帅丶 | 来源:发表于2018-12-03 09:31 被阅读0次

数据提取器

1 CSS选择器
    1. 标签选择器:直接写标签名,比如title就表示选择 title 这个标签。
    1. 类选择器:以小数点开头,比如.nav就表示选择所有 class 属性为nav的 DOM 元素。
    1. ID 选择器:以 # 开头,比如#content就表示选择 id 属性为content的 DOM 元素。(跟据 css 规范,id 属性值应该是唯一的,不能存在其他具有相同 id 的元素)
    1. 属性选择器:写在[]括号内,如a[href="https://example.org"]
    1. 伪元素选择器:伪元素选择器来自Css3规范,使用两个冒号引导。最常用的应该是title::text这个伪元素。(不过 css3 规范里好像没有 text 伪元素)
    1. 关系选择器:基于关系的选择器-MDN

举个栗子

http://news.163.com/17/1227/10/D6LH6VHC00019A1E.html用该网址为例子

image.png
获取标题和下面的图片
image.png
查看标题的源代码,在id=epContentLeft的div下的h1下的文本
在控制端输入
scrapy shell http://news.163.com/17/1227/10/D6LH6VHC00019A1E.html
执行response.css('div#epContentLeft >h1::text').extract_first()
div#epContentLeft找到所属的div
'> h1表示元素的任一子元素h1(也就是直系后代)
extract_first()第一个元素
extract()列表元素
image.png

执行response.css('div#endText img::attr(src)').extract_first()
获取图片的地址

2 Xpath选择器

xpath路径表达式
用法详解

image.png
image.png
注意:一个标签的属性值可以存在多个,比如 <div class=“name1 name2 name3”>hello</div>,这种情况下进行定位的时候,把所有类名都写上就比较麻烦。这时候可以选取一个能唯一代表该 div 的类名,假设我们选了 name2,然后可以使用 contains(@attr, "value") 方法,该方法表示,只要标签的属性包含指定的值就可以
image.png

举个例子

  • 获取标题
    response.xpath('//div[@id="epContentLeft"]/h1/text()').extract_first()
    /h1当前节点下的h1
    //h1 任意节点下的h1
    获取div下的第二个p的值
    response.xpath('//div[@id="endText"]/p[2]/text()').extract()
    获取图片地址
    response.xpath('//div[@id="endText"]//img/@src').extract_first()
    image.png

Lxml

跟bs4,都可以补全没闭合的标签

  • 解析html字符串,使用lxml.etree.HTML进行解析,代码:
text='''<div> 
            <li class="item-1"><a >first item</a></li>
            <li class="item-1"><a href="link2.html">second item</a>
            <li class="item-inactive"><a href="link3.html">third item</a></li>
            <li class="item-1"><a href="link4.html">fourth item</a>
            <li class="item-0"><a href="link5.html">fifth item</a>
            </ul> </div>'''
htmlEel=etree.HTML(text)#生成HTML相关对象
all_msg=etree.tostring(htmlEel,encoding='utf-8').decode('utf-8')
print(htmlEel.xpath('//li[@class="item-1"]//a//text()'))

即使不规范,也能补全,解析出来,带答案中<ul>,<li>都存在补全的问题,依然能解析出来

Lxml与xpath结合
<table class="tablelist" cellpadding="0" cellspacing="0">
    <tbody>
    <tr class="h">
        <td class="l" width="374">职位名称</td>
        <td>职位类别</td>
        <td>人数</td>
        <td>地点</td>
        <td>发布时间</td>
    </tr>
    <tr class="even">
        <td class="l square"><a target="_blank"
                                href="position_detail.php?id=46042&amp;keywords=&amp;tid=87&amp;lid=2156">25663-泛互联网行业解决方案专家(北京)</a>
        </td>
        <td>技术类</td>
        <td>1</td>
        <td>北京</td>
        <td>2018-11-30</td>
    </tr>
    <tr class="odd">
        <td class="l square"><a target="_blank"
                                href="position_detail.php?id=46034&amp;keywords=&amp;tid=87&amp;lid=2156">26381-政务业务高级前端工程师(北京)</a>
        </td>
        <td>技术类</td>
        <td>1</td>
        <td>北京</td>
        <td>2018-11-30</td>
    </tr>
    <tr class="even">
        <td class="l square"><a target="_blank"
                                href="position_detail.php?id=46036&amp;keywords=&amp;tid=87&amp;lid=2156">23674-接入平台组组长</a>
        </td>
        <td>技术类</td>
        <td>1</td>
        <td>北京</td>
        <td>2018-11-30</td>
    </tr>
    <tr class="odd">
        <td class="l square"><a target="_blank"
                                href="position_detail.php?id=46037&amp;keywords=&amp;tid=87&amp;lid=2156">23674-前端开发组组长</a>
        </td>
        <td>技术类</td>
        <td>1</td>
        <td>北京</td>
        <td>2018-11-30</td>
    </tr>
    <tr class="even">
        <td class="l square"><a target="_blank"
                                href="position_detail.php?id=46039&amp;keywords=&amp;tid=87&amp;lid=2156">25663-泛文娱行业解决方案专家(北京)</a>
        </td>
        <td>技术类</td>
        <td>1</td>
        <td>北京</td>
        <td>2018-11-30</td>
    </tr>
    <tr class="odd">
        <td class="l square"><a target="_blank"
                                href="position_detail.php?id=45991&amp;keywords=&amp;tid=87&amp;lid=2156">22989-大数据后台开发工程师</a>
        </td>
        <td>技术类</td>
        <td>1</td>
        <td>北京</td>
        <td>2018-11-30</td>
    </tr>
    <tr class="even">
        <td class="l square"><a target="_blank"
                                href="position_detail.php?id=45992&amp;keywords=&amp;tid=87&amp;lid=2156">22989-大数据前端开发工程师</a>
        </td>
        <td>技术类</td>
        <td>1</td>
        <td>北京</td>
        <td>2018-11-30</td>
    </tr>
    <tr class="odd">
        <td class="l square"><a target="_blank"
                                href="position_detail.php?id=45994&amp;keywords=&amp;tid=87&amp;lid=2156">22989-大数据和人工智能高级开发工程师(北京)</a>
        </td>
        <td>技术类</td>
        <td>1</td>
        <td>北京</td>
        <td>2018-11-30</td>
    </tr>
    <tr class="even">
        <td class="l square"><a target="_blank"
                                href="position_detail.php?id=45985&amp;keywords=&amp;tid=87&amp;lid=2156">25663-泛互联网解决方案架构师(北京/上海/深圳)(北京)</a>
        </td>
        <td>技术类</td>
        <td>1</td>
        <td>北京</td>
        <td>2018-11-30</td>
    </tr>
    <tr class="odd">
        <td class="l square"><a target="_blank"
                                href="position_detail.php?id=45988&amp;keywords=&amp;tid=87&amp;lid=2156">25663-泛互联网售中架构师(北京)</a>
        </td>
        <td>技术类</td>
        <td>1</td>
        <td>北京</td>
        <td>2018-11-30</td>
    </tr>

    </tbody>
</table>

代码:

#1.获取所有tr标签
#2.获取第2个tr
#3获取class 等于even的标签
# 4获取所有a标签的href
#5获取所有职位信息,纯文本
from  lxml import etree
parse=etree.HTMLParser(encoding='utf-8')
htmlELE=etree.parse('tenxun.html',parser=parse)
#任务1
# trs=htmlELE.xpath('//tr')
# for tr in trs:
#     #把元素对象转成字符串
#     print(etree.tostring(tr,encoding='utf-8').decode("utf-8"))
#任务2
# trs=htmlELE.xpath('//tr[2]')[0]# xpath用于是list返回,所有给0,取出数据
# print(etree.tostring(trs,encoding='utf-8').decode("utf-8"))
#任务3
# trs=htmlELE.xpath('//tr[@class="even"]')
# for tr in trs:
#   #把元素对象转成字符串
#      print(etree.tostring(tr,encoding='utf-8').decode("utf-8"))
#任务4
# a_s=htmlELE.xpath('//a/@href')
# for a in a_s:
#   #已经是字符串了,不用在转了,直接打印,
#   print(a)
#任务5
trs=htmlELE.xpath('//tr[position()>1]') #进行过滤
for tr in trs :
    title=tr.xpath('.//a/text()')[0] #//会重复,原因是//又会重新全局查找 加.表示当前元素下
    cate=tr.xpath('./td[2]/text()')[0]
    time = tr.xpath('./td[5]/text()')[0]
    print(title+"\n"+"-"+cate+time)

相关文章

网友评论

      本文标题:Xpath,CSS选择器

      本文链接:https://www.haomeiwen.com/subject/vbuhcqtx.html