當咱們取得了網頁的response以後,最關鍵的就是如何從繁雜的網頁中把咱們須要的數據提取出來,python從網頁中提取數據的包不少,經常使用的有下面的幾個:css
你能夠在scrapy中使用任意你熟悉的網頁數據提取工具,可是,scrapy自己也爲咱們提供了一套提取數據的機制,咱們稱之爲選擇器(seletors),他們經過特定的 XPath 或者 CSS 表達式來「選擇」 HTML文件中的某個部分。XPath 是一門用來在XML文件中選擇節點的語言,也能夠用在HTML上。 CSS 是一門將HTML文檔樣式化的語言。選擇器由它定義,並與特定的HTML元素的樣式相關連。
Scrapy選擇器構建於 lxml 庫之上,這意味着它們在速度和解析準確性上很是類似。下面咱們來了解scrapy選擇器。html
scrapy中調用選擇器的方法很是的簡單,下面咱們從實例中進行學習。
咱們仍是以博客園首頁的信息做爲例子,演示使用選擇器抓取數據,下圖是首頁的html信息,咱們下面就是抓取標題,連接,閱讀數,評論數。
python
import scrapy from scrapy.selector import Selector class Cnblog_Spider(scrapy.Spider): name = "cnblog" allowed_domains = ["cnblogs.com"] start_urls = [ 'https://www.cnblogs.com/', ] def parse(self, response): selector = Selector(response=response) title = selector.xpath('//a[@class="titlelnk"]/text()').extract() link = selector.xpath('//a[@class="titlelnk"]/@href').extract() read = selector.xpath('//span[@class="article_comment"]/a/text()').extract() comment = selector.xpath('//span[@class="article_view"]/a/text()').extract() print('這是title:',title) print('這是連接:', link) print('這是閱讀數', read) print('這是評論數', comment)
選擇器的使用能夠分爲下面的三步:正則表達式
from scrapy.selector import Selector
selector = Selector(response=response)
selector.xpath()
或者selector.css()
固然你可使用xpath
或者css
中的任意一種或者組合使用,怎麼方便怎麼來,至於xpath和css語法,你能夠去額外學習,仔細觀察,你會發現每一個選擇器最後都有一個extract()
,你能夠嘗試去掉這個看一下,區別在於,當你沒有使用extract()
的時候,提取出來的內容依然具備選擇器屬性,簡而言之,你能夠繼續使用裏面的內容進行提取下級內容,而當你使用了extract()
以後,提取出來的內容就會變成字符串格式了。咱們進行多級提取的時候,這會頗有用。值得注意的是,選擇器提取出來的內容是放在列表裏面的,即便沒有內容,那也是一個空列表,下面咱們運行這個爬蟲,你會發現內容已經被提取出來了。
dom
事實上,咱們能夠徹底不用那麼麻煩,由於scrapy爲咱們提供了選擇器的簡易用法,當咱們須要選擇器的時候,只要一步就能夠了,以下:scrapy
import scrapy class Cnblog_Spider(scrapy.Spider): name = "cnblog" allowed_domains = ["cnblogs.com"] start_urls = [ 'https://www.cnblogs.com/', ] def parse(self, response): title = response.xpath('//a[@class="titlelnk"]/text()').extract() link = response.xpath('//a[@class="titlelnk"]/@href').extract() read = response.xpath('//span[@class="article_comment"]/a/text()').extract() comment = response.xpath('//span[@class="article_view"]/a/text()').extract() print('這是title:', title) print('這是連接:', link) print('這是閱讀數', read) print('這是評論數', comment)
能夠看到,咱們直接使用response.xpath()
就能夠了,並無導入什麼,實例化什麼,能夠說很是方便了,固然直接response.css()
同樣能夠。ide
scrapy爲咱們提供的選擇器還有一些其餘的特色,這裏咱們簡單的列舉工具
>>> response.xpath('//title/text()') [<Selector (text) xpath=//title/text()>] >>> response.css('title::text') [<Selector (text) xpath=//title/text()>]
response.xpath('//span[@class="article_view"]/a/text()').extract_first()
這樣咱們就拿到了第一個匹配的數據,固然,咱們以前提到了選擇器返回的數據是一個列表,那麼你固然可使用response.xpath('//span[@class="article_view"]/a/text()').extract()[0]
拿到第一個匹配的數據,這和response.xpath('//span[@class="article_view"]/a/text()')[0].extract()
效果是同樣的,值得注意的是,若是是空列表,這兩種方法的區別就出現了,extract_first()會返回None,然後面的那種方法,就會因列表爲空而報錯。extract_first(default='not-found')
。你會發現,以前咱們匹配的閱讀數,評論數都會有漢字在裏面,若是咱們只想提取裏面的數字呢,這個時候就可使用正則表達式和選擇器配合來實現,好比下面:學習
import scrapy class Cnblog_Spider(scrapy.Spider): name = "cnblog" allowed_domains = ["cnblogs.com"] start_urls = [ 'https://www.cnblogs.com/', ] def parse(self, response): read = response.xpath( '//span[@class="article_comment"]/a/text()').re('\d+') comment = response.xpath( '//span[@class="article_view"]/a/text()').re('\d+') print('這是閱讀數', read) print('這是評論數', comment)
運行一下,能夠看到,效果就出來了。
url