假如: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]')