当咱们取得了网页的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