数据提取器
1 CSS选择器
- 标签选择器:直接写标签名,比如
title
就表示选择 title 这个标签。
- 标签选择器:直接写标签名,比如
- 类选择器:以小数点开头,比如
.nav
就表示选择所有 class 属性为nav
的 DOM 元素。
- 类选择器:以小数点开头,比如
- ID 选择器:以 # 开头,比如
#content
就表示选择 id 属性为content
的 DOM 元素。(跟据 css 规范,id 属性值应该是唯一的,不能存在其他具有相同 id 的元素)
- ID 选择器:以 # 开头,比如
-
属性选择器:写在[]括号内,如
a[href="https://example.org"]
-
属性选择器:写在[]括号内,如
- 伪元素选择器:伪元素选择器来自Css3规范,使用两个冒号引导。最常用的应该是
title::text
这个伪元素。(不过 css3 规范里好像没有 text 伪元素)
- 伪元素选择器:伪元素选择器来自Css3规范,使用两个冒号引导。最常用的应该是
- 关系选择器:基于关系的选择器-MDN
举个栗子
http://news.163.com/17/1227/10/D6LH6VHC00019A1E.html用该网址为例子
![](https://img.haomeiwen.com/i4908477/2086e2a2d42e60cc.png)
获取标题和下面的图片
![](https://img.haomeiwen.com/i4908477/65403e2750f47a07.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()列表元素
![](https://img.haomeiwen.com/i4908477/4b1adba71a3c5cbc.png)
执行response.css('div#endText img::attr(src)').extract_first()
获取图片的地址
2 Xpath选择器
![](https://img.haomeiwen.com/i4908477/6fe34a9f7447ec82.png)
![](https://img.haomeiwen.com/i4908477/211572fa4c747a2e.png)
注意
:一个标签的属性值可以存在多个,比如 <div class=“name1 name2 name3”>hello</div>,这种情况下进行定位的时候,把所有类名都写上就比较麻烦。这时候可以选取一个能唯一代表该 div 的类名,假设我们选了 name2,然后可以使用 contains(@attr, "value") 方法,该方法表示,只要标签的属性包含指定的值就可以![](https://img.haomeiwen.com/i4908477/d0338e8f206069a7.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&keywords=&tid=87&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&keywords=&tid=87&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&keywords=&tid=87&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&keywords=&tid=87&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&keywords=&tid=87&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&keywords=&tid=87&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&keywords=&tid=87&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&keywords=&tid=87&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&keywords=&tid=87&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&keywords=&tid=87&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)
网友评论