假如:css 选择其中若是div元素下面有子节点a 和孙节点 imagcss
对比xpath中的'/‘仅仅指子元素不包括孙节点,可用’//‘取全部后辈节点。选择div下面的第二个a标签能够用 ('div/a[2]')程序员
同时须要注意,若是选择其中涉及到多个样式须要用到或的时候,css中没有或的用法,须要作判断,相对来讲,用xpath的’|‘比较简单。shell
<a href="https://blog.csdn.net/qq_42231391/article/details/83749637"
target="_blank">Python的崛起,百万程序员被影响?真相…… </a>
根据部份内容匹配到这个a标签的xpath语法:"//a[contains(text(),"Python的崛起")]",这样就能够匹配到了scrapy
//div[contains(@class,"td-01")]
表示属性中含有的标签classtd-01div
要取到上面全部的关注者人数和被浏览人数:ide
xpath两种方式(推荐使用1):ui
css方式:css('.NumberBoard.QuestionFollowStatus-counts.NumberBoard--divider div strong::text')spa
补充:这里只想取到关注着人数的时候用css('.NumberBoard.QuestionFollowStatus-counts.NumberBoard--divider div:nth-child(1) .NumberBoard-itemValue::text')无效,浏览人数和关注人数都取出来了。.net
在知乎提取话题浏览人数与关注人数的时候,用xpath方式:提取关注人数:code
response.xpath(’//div[contains(@class, "NumberBoard") and contains(@class, "QuestionFollowStatus-counts") and contains(@class, "NumberBoard-divider")]/div[1]//strong/text()')blog
提取浏览人数:
response.xpath(’//div[contains(@class, "NumberBoard") and contains(@class, "QuestionFollowStatus-counts") and contains(@class, "NumberBoard-divider")]/div[2]//strong/text()')
此方式在shell 中用scrapy shell进入网页时候能够提取成功,可是放到scrapy中运行以后就少了一个字段,而后改用css方法以下:
提取关注人数:
response.css('.NumberBoard.QuestionFollowStatus-counts.NumberBoard--divider div:nth-child(1) .NumberBoard-itemInner .NumberBoard-itemValue::text')
提取浏览人数:
response.css('.NumberBoard.QuestionFollowStatus-counts.NumberBoard--divider div:nth-child(2) .NumberBoard-itemInner .NumberBoard-itemValue::text')
一样在shell中试了均可以提取出来,可是scrapy中的时候item字段的值提取的同样,都是浏览人数。
Books/book[@author='John' and @year='2009' and @language='En']
选择class="c",而且包含id属性的标签。
response.css('div.c[id]')
至关于xpath:
response.xpath('//div[@class="c" and @id]')
//input[starts-with(@name,'name1')] 查找name属性中开始位置包含'name1'关键字的页面元素
//input[contains(@name,'na')] 查找name属性中包含na关键字的页面元素
CSS选择其 src 属性中包含 "abc" 子串的每一个 <a> 元素
a[src*="abc"]
选择文本中包含“難得的大集合,”的标签
response.xpath('//*[contains(text(),"難得的大集合,")]')
特殊的以下:
<div>
<ul id="side-menu">
<li class="active">
<a href="#">
<i>图标</i>
电子帐户
<span>箭头</span>
</a>
<ul class="nav">
<li>子菜单1</li>
<li>子菜单2</li>
</ul>
</li>
</ul>
</div>
电子帐户这几个字没有被一个明确的标签包裹。此时再用//ul[@id='side-menu']/li/a[contains(text(),"电子帐户")]表达式就到不到了.不过能够借助string()
, 将a标签里边的东西所有转换成字符串, 再用contains()
判断:
//ul[@id='side-menu']/li/a[contains(string(), '电子帐户')]
选择文本包含“下页”的a标签的href链接
response.css('a:contains("下页")::attr(href)')
from scrapy import Selector
target = """ <div class="c" id="C_4364295984831768"> <span class="kt">[热门]</span> <a href="/u/3265432182">ohmy金雨</a> <img src="https://h5.sinaimg.cn/upload/2016/05/26/319/donate_btn_s.png" alt="M">: <span class="ctt">回复 <a href="/n/Edward-9">@Edward-9</a> :人生到底有没有收获 <img alt="[喵喵]" src="//h5.sinaimg.cn/m/emoticon/icon/others/d_miao-61fe2a7aaa.png" style="width:1em; height:1em;"> </span> <a href="/spam/?cid=4364295984831768&fuid=3265432182&type=2&rl=1">举报</a> <span class="cc"> <a href="/attitude/HqYDckgXK/update?object_type=comment&uid=6433679945&rl=1&st=9b7c7b">赞[33]</a> </span> <span class="cc"> <a href="/comments/reply/HqYvwwJc0/4364295984831768?rl=1&st=9b7c7b">回复</a> </span> <span class="ct">04月23日 17:45 来自网页</span> </div> """ selector = Selector(text=target) print(selector.css('a:nth-child(1)::text').extract()) # 原觉得是找到第一个 a标签下面的文本即 “ohmy金雨”,结果不是。
print(selector.css('a:nth-child(2)::text').extract()) # 此选择也不是第二个 a标签下的文本,而是后代标签的第一个。 输出结果: ['@Edward-9', '赞[33]', '回复'] ['ohmy金雨']
分析:以前一直觉得css中的nth-child(n)和xpath中的[n]是同样的道理,其实并非,花了整整2个小时的实践才知道并非这样的。
代码中的 a:nth-child(1) 实际上意思是找到全部后代节点中做为第一个子节点的a标签,若是第一个后代节点不是a标签则不返回。而不是后代标签中的第一个a标签,
当用 print(selector.css(':nth-child(2)').extract())的时候是就找到全部的做为第二个子节点存在的标签。输出:
['<a href="/u/3265432182">ohmy金雨</a>', '<img alt="[喵喵]" src="//h5.sinaimg.cn/m/emoticon/icon/others/d_miao-61fe2a7aaa.png" style="width:1em; height:1em;">']
response.css('div.c[id]')