创建一个工程:scrapy startproject xxpro,在终端输入,执行后会在你指定的目录下生成与你创建的工程名称相同的一个文件夹,文件夹下包含了一个spiders包,必须要存放一个爬虫的源文件。 settings.py是对应的工程配置文件:其中,可以做以下修改,robots协议,显示指定类型的日志信息。
在spides子目录中创建一个爬虫文件:首先要cd到 当前的工程目录中,即 xxxpro。 然后创建爬虫文件: scrapy genspider spiderName www.xxx.com(爬虫的名字,起始的url) 其中,first.py文件含义如下:
import scrapy class FirstSpider(scrapy.Spider): #name:爬虫文件的名称,就是爬虫源文件的唯一标识 name = 'first' #allowed_domains允许的域名:允许访问的url,用来限定urls列表中哪些可以请求发送,一般不使用allowed_domains allowed_domains = ['www.xxx.com'] #start_urls起始的url列表:该列表中的URL会被scrapy自动进行请求发送 start_urls = ['http://www.xxx.com/'] #parse用作数据解析:response参数表示的就是请求成功后返回的响应对象,每一个url都会调用一次parse def parse(self, response): pass 执行工程:scrapy crawl spiderName注意:在创建好爬虫文件后,首先要在配置文件中修改:USER_AGENT=‘伪装的UA’,ROBOTSTXT_OBEY = False,LOG_LEVEL = ‘ERROR’。
获取字符串数据 :
import scrapy class FirstSpider(scrapy.Spider): name = 'first' #start_urls起始的url列表:该列表中的URL会被scrapy自动进行请求发送 start_urls = ['https://www.qiushibaike.com/text/'] def parse(self, response): #解析作者的名称和段子内容 div_list = response.xpath('//div[@class="article block untagged mb15 typs_long"]') #xpath返回的是列表,但是列表元素一定是selector类型的对象 author = div_list.xpath('./div[1]/a[2]/h2/text()')[0].extract() #列表调用了extract之后,表示将列表中每一个selector对象中data对应的字符串提取了出来 content = div_list.xpath('./a/div//text()').extract() #将字符串提取出来后,存进的仍一个列表 #将列表转字符串 content = ''.join(content) print(author,content)未使用extract()之前,返回的是selector对象。使用之后之后返回的是data中的值的列表,需要用join转成字符串。
b.在item类中定义相关的属性
import scrapy class FirstproItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() author = scrapy.Field() content= scrapy.Field() passc.将解析的数据封装存储到item类型的对象中 d.将item类型的对象提交给管道进行持久化存储 e.在管道类的process_item中要将其接收到的item对象中存储的数据进行持久化存储操作
class FirstproPipeline: #专门用来处理item类型的对象 #该方法可以接收爬虫文件提交过来的的item对象 #该方法每接收到一个item就会被调用一次 fp = None #重写父类的一个方法:该方法只在开始爬虫时执行一次 def open_spider(self,spider): print('start spider!!!') self.fp = open('./first.txt','w',encoding='utf-8') def process_item(self, item, spider): author = item['author'] content = item['content'] self.fp.write(author + ':' + content + '\n') return item def close_spider(self,spider): print('End spider!!!') self.fp.close()f.在配置文件中开启管道 (2)好处:通用性强。编码稍繁琐。
(3)面试题:将爬取的数据一份存储到本地一份存储到数据库,如何实现? a.管道文件中一个管道类对应的是将数据存储到一种平台 b.爬虫文件提交的item只会给管道文件中第一个被执行的管道类接受 c.process_item中的return item 表示将item传递给下一个即将被执行的管道类。也就是说return item可以将item交给下一个管道类,在编码时要注意这一点。