import scrapy class JobboleSpider(scrapy.Spider): name = 'jobbole' allowed_domains = ['blog.jobbole.com'] start_urls = ['http://blog.jobbole.com/'] def parse(self, response): re_selector = response.xpath('//*[@id="post-110287"]/div[1]/h1/text()')
<html><body><div>
<ul>
<li class="item-0"><a href="link1.html"><span>first item</span></a></li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-inactive"><a href="link3.html">third item</a></li>
<li class="item-1"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
</ul>
</div></body></html>
首先選中href屬性爲link4.html的a節點,而後再獲取其父節點,而後再獲取其class屬性 result1 = response.xpath('//a[@href="link4.html"]/../@class') 咱們也能夠經過parent::來獲取父節點 result2 = response.xpath('//a[@href="link4.html"]/parent::*/@class')
獲取class爲item-1的li節點文本, result3 = response.xpath('//li[@class="item-0"]/a/text()') 返回結果爲['first item', 'fifth item']
獲取全部li節點下的全部a節點的href屬性 result4 = response.xpath('//li/a/@href') 返回結果爲['link1.html', 'link2.html', 'link3.html', 'link4.html', 'link5.html']
result = response.xpath('//li[1]/a/text()') #選取第一個li節點 result = response.xpath('//li[last()]/a/text()') #選取最後一個li節點 result = response.xpath('//li[position()<3]/a/text()') #選取位置小於3的li節點,也就是1和2的節點 result = response.xpath('//li[last()-2]/a/text()') #選取倒數第三個節點
1)返回第一個li節點的全部祖先節點,包括html,body,div和ul result = response.xpath('//li[1]/ancestor::*') 2)返回第一個li節點的<div>祖先節點 result = response.xpath('//li[1]/ancestor::div') 3)返回第一個li節點的全部屬性值 result = response.xpath('//li[1]/attribute::*') 4)首先返回第一個li節點的全部子節點,而後加上限定條件,選組href屬性爲link1.html的a節點 result = response.xpath('//li[1]/child::a[@href="link1.html"]') 5)返回第一個li節點的全部子孫節點,而後加上只要span節點的條件 result = response.xpath('//li[1]/descendant::span') 6)following軸可得到當前節點以後的全部節點,雖然使用了*匹配,可是又加了索引選擇,因此只獲取第2個後續節點,也就是第2個<li>節點中的<a>節點 result = response.xpath('//li[1]/following::*[2]') 7)following-sibling可獲取當前節點以後的全部同級節點,也就是後面全部的<li>節點 result = response.xpath('//li[1]/following-sibling::*')
<li class="li li-first"><a href="link.html">first item</a></li> result5 = response.xpath('//li[@class="li"]/a/text()') 返回值爲空,由於這裏HTML文本中li節點爲class屬性有2個值li和li-first,若是還用以前的屬性匹配就不行了,須要用contain()函數 正確方法以下 result5 = response.xpath('//li[contains(@class, "li")]/a/text()') contains()方法中,第一個參數爲屬性名,第二個參數傳入屬性值,只要此屬性名包含所傳入的屬性值就可完成匹配
from lxml import etree text = ''' <li class = "li li-first" name="item"><a href="link.html">first item</a></li>
''' html = etree.HTML(text) result6 = html.xpath('//li[contains(@class, "li") and @name="item"]/a/text()') print(result)
>>> title = response.xpath('//div[@class="entry-header"]/h1/text()') >>> title [<Selector xpath='//div[@class="entry-header"]/h1/text()' data='2016 騰訊軟件開發面試題(部分)'>] >>> title.extract() ['2016 騰訊軟件開發面試題(部分)'] >>> title.extract()[0] '2016 騰訊軟件開發面試題(部分)'
>>> title.extract_first() '2016 騰訊軟件開發面試題(部分)'
>>> response.xpath("//p[@class='entry-meta-hide-on-mobile']/text()").extract()[0].strip().replace("·","").strip() '2017/02/18'
>>> response.xpath("//span[contains(@class, 'vote-post-up')]/h10/text()").extract() ['2'] >>> response.xpath("//span[contains(@class, 'vote-post-up')]/h10/text()").extract()[0] '2'
>>> int(response.xpath("//span[contains(@class, 'vote-post-up')]/h10/text()").extract()[0]) 2
>>> response.xpath("//span[contains(@class, 'bookmark-btn')]/text()").extract()[0] ' 28 收藏'
>>> string = response.xpath("//span[contains(@class, 'bookmark-btn')]/text()").extract()[0] >>> import re >>> pattern = re.match(".*?(\d+).*", string) >>> pattern.group(1) '28'
能夠簡寫爲css
>>> response.xpath("//span[contains(@class, 'bookmark-btn')]/text()").re('.*?(\d+).*') ['28'] >>> response.xpath("//span[contains(@class, 'bookmark-btn')]/text()").re('.*?(\d+).*')[0] '28'
找到不是以"評論"結尾的元素 >>> response.xpath("//p[@class='entry-meta-hide-on-mobile']/a/text()").extract() ['職場', ' 9 評論 ', '面試'] >>> tag_list = response.xpath("//p[@class='entry-meta-hide-on-mobile']/a/text()").extract() >>> [element for element in tag_list if not element.strip().endswith("評論")] ['職場', '面試'] >>> tag_choose=[element for element in tag_list if not element.strip().endswith("評論")] >>> tags=",".join(tag_choose) >>> tags '職場,面試'
li a
|
選取全部li下的全部a節點
|
ul + p
|
選擇ul後面的第一個p元素,ul和p是兄弟節點
|
div#container>ul
|
選取id爲container的div標籤,下邊的第一個ul子元素
|
ul ~ p
|
選取與ul相鄰的全部p元素
|
a[title]
|
選取全部含有title屬性的a元素
|
a::attr(href)
|
獲取全部a元素的href屬性值
|
a[href="http://jobbole.com"]
|
選取全部href屬性爲http://jobbole.com值的a元素
|
a[href*="jobble"]
|
選取全部href屬性包含jobbole的a元素
|
a[href^="http"]
|
選取全部href屬性值以http開頭的a元素
|
a[href$=".jpg"]
|
選取全部href屬性值以.jpg結尾的a元素
|
input[type=radio]:checked
|
選擇選中的radio的元素
|
div:not(#container)
|
選取全部id不等於container的div元素
|
li:nth-child(3)
|
選取第三個li元素
|
tr:nth-child(2n)
|
選取偶數位的tr元素
|
>>> response.css(".entry-header h1").extract() ['<h1>2016 騰訊軟件開發面試題(部分)</h1>'] >>> response.css(".entry-header h1::text").extract()[0] '2016 騰訊軟件開發面試題(部分)'
>>> response.css("p.entry-meta-hide-on-mobile::text").extract()[0].strip().replace(" ·","") '2017/02/18'
>>> response.css(".vote-post-up h10::text").extract()[0] '2'
>>> response.css(".bookmark-btn::text").extract()[0] ' 28 收藏'
>>> string = response.css(".bookmark-btn::text").extract()[0] >>> tag=re.match(".*?(\d+).*", string) >>> tag.group(1) '28'
其實正則re也是scrapy的內置模塊,能夠簡寫爲以下html
>>> response.css(".bookmark-btn::text").re('.*?(\d+).*') ['28'] >>> response.css(".bookmark-btn::text").re('.*?(\d+).*')[0] '28'
response.css("div.entry").extract()[0]
>>> response.css("p.entry-meta-hide-on-mobile a::text").extract() ['職場', ' 9 評論 ', '面試']