scrapy提供了兩種提取方法,Xpath和Css。
Xpath用起來覺得好麻煩,有點笨,我還是比較喜歡Css的提取方式。因為CSS定位語法比Xpath簡潔,定位方式更靈活多樣,可以使用#id來根據ID獲取元素,以及使用.class來根據class獲取元素.用XPath實現的話都不會那么簡潔,反過來呢,XPath可以使用,來返回到DOM樹的上層節點中。anyway先操練起來!
http://blog.jobbole.com/102337/
F12來打開網頁源代碼,也可以點擊firefox旁邊那個小蜜蜂??
我現在想提取“我想對所有新手程序員說些肺腑之言”
關鍵詞:entry-header;? ? h1
我們現在用mac終端來測試一下提取結果,進入虛擬環境
輸入:
scrapy shellhttp://blog.jobbole.com/102337/
1.提取title
>>> response.css(".entry-header h1::text").extract()[0]
'我想對所有新手程序員說些肺腑之言'
解釋一下:
這個點.? 表示 選擇所有class包含container的節點
extract()提取出他的值
[0]
::text偽類選擇器
這里要用py3,編碼才是Unicode中文字,不然py2的話,還是utf8字符串的顯示模式。
2.提取日期
>>> response.css("p.entry-meta-hide-on-mobile::text").extract()[0].strip()
'2017/05/27 ·'
3、提取點贊數
>>> response.css(".vote-post-up? h10::text").extract()[0]
'3'
4、提取收藏數
>>> response.css(".bookmark-btn::text").extract()[0]
' 7 收藏'
用正則表達式把7提取出來
進入python環境,測試一下正則表達式
是騾子是馬拉出來溜溜,不行慢慢調試
importre
match_re=re.match(".*?(\d+).*"," 7 收藏")
ifmatch_re:
print(match_re.group(1))
yeah!7出來了
5、提取評論數
我用了比較笨的方法提取的:
>>> response.css(".btn-bluet-bigger::text").extract()
[' ', ' 贊', ' 7 收藏', ' 3 評論']
>>> response.css(".btn-bluet-bigger::text").extract()[3]
' 3 評論'
>>> response.css(".btn-bluet-bigger::text").extract()[3].strip()
'3 評論'
Bobby老師是這么做的,
response.css("a[href='#article-comment'] span::text").extract()[0]
走神中:
自己做個小練習:
把博士帽那個240聲望值提取一下。
>>> response.css("#author-bio .author-bio-info-block a::text").extract()[2].strip()
'240'
哎,還是我的笨方法好用,先這樣吧,以后慢慢優化吧
6.提取內容
>>> response.css ( ".entry" ).extract()[0]或者
>>> response.css ( "div.entry" ).extract()[0]
都可以
7、提取tag標簽
>>> response.css(".entry-meta-hide-on-mobile a::text").extract()
['開發', ' 3 評論 ', '程序員']
如何把3評論給扔掉呢?
用數組的方式在python里面簡單寫段代碼來驗證一下
tag_list= ['開發',' 3 評論 ','程序員']
tag_list= [elementforelementintag_listif notelement.strip ().endswith ("評論")]
tags =",".join (tag_list)
print(tag_list)
Xpath基本語法
舉例元素標簽為artical標簽
一:
artical 選取所有artical元素的子節點
/artical 選取根元素artical
artical/a 選取所有屬于artical的子元素a元素
//div??? 選取所有div 子元素,無論div在任何地方
artical//div? 選取所有屬于artical的div 元素,無論div元素在artical的任何位置
//@class 選取所有名為class 的屬性的
二:謂語
/artical/div[1]?? 選取所有屬于artical 子元素的第一個div元素
/artical/div[last()]? 選取所有屬于artical子元素的最后一個元素
/artical/div[last()-1] 選取所有屬于artical子元素的倒數低2個元素
//div[@lang]?? 選取所有擁有屬性為lang的元素
//div[@lang="eng"] 選取所有div下lang屬性為eng的元素
三:
/div/* 選取所有屬于div元素的所有子節點
//*??? 選取所有元素
//div[@*]?? 選取所有帶屬性的title元素
//div/a|//div/p?? 選取所有div元素的a和p 元素
//span | //ul?? 選取文檔中所有span和ul 的元素
artical/div/pl|//span? 選取所有div下的pl和文檔中所有span
注意事項:
1) 按照審查元素的寫法不一定正確,要按照網頁源碼的才行
因為不一樣,網頁源碼才是你看到的
2) 瀏覽器有自帶的復制xpath功能,firefox下載firebug插件
3) xpath有c的速度,所以按照[@class=""]準確性較高
CCS選擇器語法
* ??? ??? ??? ??? ?選擇所有節點
#container ?? ??? ?選擇id為container的節點
.container????? 選擇所有class包含container的節點
li a??????????? 選取所有li 下所有a節點
ul + p????????? 選取ul后面的第一個p元素
div#container > ul 選取id為container的div的第一個ul子元素
ul ~p ?? ??? ??? ?選取與ul相鄰的所有p元素
a[title]??????? 選取所有有title屬性的a元素
a[]? 選取所有href屬性為http://jobbole.com的a元素
a[href*="jobbole"]???? 選取所有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元素
li:nth-child(2n)????? 選取第偶數個li元素