1 创建项目:
$ scrapy startproject project_name
2 创建蜘蛛
在spiders文件夹下,创建一个文件,my_spiders.py
3 写蜘蛛:
my_spiders.py 文件下 1 创建类,继承scrapy的一个子类 2 定义一个蜘蛛名字, name = "you name" 3 定义我们要爬取的网址 4 继承scrapy的方法:start_requests(self import scrapy from scrapy.contrib.spiders import CrawlSpider, Rule from scrapy.contrib.linkextractors import LinkExtractor # 1 创建类,继承scrapy的一个子类 class mingyan(scrapy.Spider): # 2 定义一个蜘蛛名字, name = "you name",项目中 必须是唯一的 name = "mingyan" # 4 继承scrapy的方法:start_requests(self),必须返回请求列表或者生成器函数.,后续请求姜葱这些初始请求中连续生成. def start_requests(self): # 3 定义我们要爬取的网址 urls = [ 'http://lab.scrapyd.cn/page/1/', 'http://lab.scrapyd.cn/page/2/', ] for url in urls: # 爬取到的页面如何处理?提交给parse方法处理 yield scrapy.Request(url=url, callback=self.parse) def parse(self, response): ''' 20 start_requests已经爬取到页面,那如何提取我们想要的内容呢?那就可以在这个方法里面定义。,响应参数是TextResponse保存页面内容的实例. 1、定义链接; 24 2、通过链接爬取(下载)页面; 25 3、定义规则,然后提取数据; 26 就是这么个流程,似不似很简单呀? 27 ''' # 根据上面的链接提取分页,如:/page/1/,提取到的就是:1 page = response.url.split('/')[-2] # 拼接文件名,如果是第一页,最终文件名便是:mingyan-1.html filename = 'mingyan-%s.html' % page with open(filename, 'wb') as f: # 刚才下载的页面去哪里了?response.body就代表了刚才下载的页面! f.write(response.body) # 打个日志 self.log("保存文件:%s" % filename) ------------------------------简化版本------------------------- import scrapy from scrapy.contrib.spiders import CrawlSpider, Rule from scrapy.contrib.linkextractors import LinkExtractor # 1 创建类,继承scrapy的一个子类 class mingyan(scrapy.Spider): # 2 定义一个蜘蛛名字, name = "you name",项目中 必须是唯一的 name = "mingyan" # 4 简化版本,采用start_urls,但是必须定义parse方法,parse方法是scrapy的默认回调方法. start_urls = [ 'http://lab.scrapyd.cn/page/1/', 'http://lab.scrapyd.cn/page/2/', ] def parse(self, response): # 根据上面的链接提取分页,如:/page/1/,提取到的就是:1 page = response.url.split('/')[-2] # 拼接文件名,如果是第一页,最终文件名便是:mingyan-1.html filename = 'mingyan-%s.html' % page with open(filename, 'wb') as f: # 刚才下载的页面去哪里了?response.body就代表了刚才下载的页面! f.write(response.body)
5 运行蜘蛛:
#项目顶级目录下面. $scrapy crawl mingyan
第二部分:调试工具学习数据提取.
1 进入调试工具:输入命令之后,就已经进行了请求,已经获取到了首页的内容.数据保存在response对象中.
scrapy shell 'url' 当从命令行运行Scrapy shell时,请记住始终将URL括在引号中,否则包含参数(即&字符)的url 将不起作用。 在Windows上,请使用双引号: 例如: $ scrapy shell "http://http://lab.scrapyd.cn/"
2 后面就可以进行调试验证:
提取方法1 css----------------------------------- >>>response.css("title") #结果得到一个类似列表的对象selectorList,包含xml/html元素对象里列表,可以进一步查询和提取数据. [] >>>response.css("title::text").extract() #从结果集中提取文本,::text意味着直接在元素内选择文本元素 里的内容,不包含标签. ['Quotes to Scrape'] >>>response.css("title").extract() #如果不指定::text,那么将获得完整的title元素,包括标签. >>>response.css("title::text").extract_first() #提取结果集中的第一个元素,extract()提取的是一个列表.extract_first()可以避免IndexError和返回None. ' Quotes to Scrape ' >>>response.css("title::text").re(r"Quotes.*") #也可以用正则表达式的方法提取 ['Quotes to Scrape'] >>>response.css("title:;text").re(r"(\w+)to(\w+)') ['Quotes', 'Scrape'] 提取方法2 XPath------------------------------------------ >>>response.xpath("//title") [] >>>response.xpath("//title/text()").extract_first() 'Quotes to Scrape'
第三部分自动进行爬取:
1 编写解析方法,自动解析数据:
def parse(self): mingyan_list = response.css("div.quote") next_page = response.css("li.next a ::attr(href)").extract_first() if next_page is not None: next_page = response.urljoin(next_page) yield scrapy.Request(next_page,callback=self.parse) for mingyan in mingyan_list: text = mingyan.css('.text::text').extract_first() #提取名言 author = mingyan.css('.author::text').extract_first() #提取作者 tags = mingyan.css('.tags .tag::text').extract() #提取标签 tags = ','.join(tags) fileName = '%s-语录.txt' % author #爬取内容存入文件,文件名为作者-语录.txt f=open(fileName,'a+') #追加写入文件 f.write(text) #写入名言内容 f.write('\n') #换行 f.write('标签'+tags) #写入标签 f.close()
2 方法介绍:
1 response.urljoin(url) 这个方法获取网页绝对地址,就是将页面中的相对地址和页面拼接,构建完整的绝对URL 2 scrapy.request(url,callback=function) 这个函数用来请求页面,也就是爬取数据. 3 css选择器,支持attr, >>> response.css('li.next a::attr(href)').extract_first() '/page/2/' 4 创建请求的快捷方式: response.follow(url,callback=self.parse)#这个url可以使相对url,也就是不用调用urljoin方法,其返回的是一个Request实例,仍然要yield url也可以是选择器. for href in response.css('li.next a::attr(href)'): yield response.follow(href, callback=self.parse) 对于元素的连接,有一个快捷方式.自动调用其href属性.必须是一个a元素,也就是通过循环,或者下标获取a. for a in response.css('li.next a'): yield response.follow(a, callback=self.parse)
3 存储已经删除的数据:
最简单的方法是使用Feed导出,json格式.由于历史原因,Scrapy会附加到给定文件而不是覆盖其内容。如果在第二次之前没有删除文件的情况下运行此命令两次,则最终会出现损坏的JSON文件。
scrapy crawl 爬虫名 -o 文件名.json(要生成文件的名字,并一json序列化),-o指定生成文件. $ scrapy crawl quotes -o quotes.json
第二种方法,json Lines格式,该JSON行格式是有用的,因为它的流状,你可以很容易地新记录追加到它。当你运行两次时,它没有相同的JSON问题。此外,由于每条记录都是一个单独的行,您可以处理大文件而无需将所有内容都放在内存中,有些工具如JQ可以帮助您在命令行中执行此操作。
scrapy crawl 爬虫名 -o 文件名.jl(要生成文件的名字,并一json序列化) $ scrapy crawl quotes -o quotes.jl
如果要使用已删除的项目执行更复杂的操作,可以编写项目管道。项目管道的占位符文件已在创建项目时为您设置tutorial/pipelines.py
。
第四部分:可传参爬虫.
1 爬虫编写
import scrapy class MingYan(scrapy.Spider): name = "MingYan" def start_requests(self): url = "http://lab.scrapyd.cn/" #获取tag,tag是命令行传过来的参数 tag = getattr(self,'tag',None) if tag is not None: url = url+'tag/' +tag yield scrapy.Request(url,self.parse) def parse(self,response): ....
2 使用:
$scrapy crawl MingYan -a tag=爱情 #tag将值传递过去. -a指定tag
第五部分,scrapy命令:
常用命令: scrapy startproject(创建项目)、 scrapy crawl XX(运行XX蜘蛛)、 scrapy shell http://www.scrapyd.cn(调试网址为http://www.scrapyd.cn的网站) 全局命令: 01 startproject scrapy startproject myproject [project_dir] 在project_dir目录下创建一个Scrapy项目。如果project_dir没有指定,project_dir将是相同的myproject。 02 03 genspider 根据蜘蛛模板创建蜘蛛的命令 scrapy genspider mydomain mydomain.com 04 05 settings 它就是方便你查看到你对你的scray设置了些神马参数 获取当前的配置信息 通过scrapy settings -h可以获取这个命令的所有帮助信息 06 07 runspider 运行蜘蛛除了使用:scrapy crawl XX之外,我们还能用:runspider,前者是基于项目运行,后者是基于文件运行,也就是说你按照scrapy的蜘蛛格式编写了一个py文件,那你不想创建项目,那你就可以使用runspider,比如你编写了一个:scrapyd_cn.py的蜘蛛,你要直接运行就是: 查看源码打印代码帮助 1 scrapy runspider scrapy_cn.py 08 09 shell 10 11 fetch 它的功效就是模拟我们的蜘蛛下载页面, scrapy fetch http://www.scrapyd.cn 如果你要把它下载的页面保存到一个html文件中进行分析,我们可以使用window或者linux的输出命令,这里演示window下如下如何把下载的页面保存: 查看源码打印代码帮助 该命令会通过scrapy downloader 讲网页的源代码下载下来并显示出来 这里有一些参数: --nolog 不打印日志 --headers 打印响应头信息 --no-redirect 不做跳转 1 scrapy fetch http://www.scrapyd.cn >d:/3.html 12 13 view fetch类似都是查看蜘蛛看到的是否和你看到的一致,便于排错,用法: scrapy view url地址 该命令会讲网页document内容下载下来,并且在浏览器显示出来 14 15 version
scrpay项目命令 crawl 运行蜘蛛 check 检查蜘蛛 list 显示有多少个蜘蛛 edit parse bench