第一种:
1. 解析函数中parse,要return [{},{},{}]-------- parse必须有return值,必须是列表套字典形式--->使用命令,可以保存到json格式中
2.执行如下命令 ----cmd
scrapy crawl 创建的爬虫名字 -o 文件名(json,pickle,csv结尾)
例子:
scrapy crawl baidu -o baidu.json
方案二:使用pipline 常用的,管道形式,可以同时存到多个位置的
1 在items.py中写一个类[相当于写django的表模型],继承scrapy.Item
2. 在类中写属性,写字段,所有字段都是scrapy.Field类型
title = scrapy.Field()
class CnblogsItem(scrapy.Item): 类名随便起
title = scrapy.Field() title,desc。。。。。。 属于字段名
desc = scrapy.Field()
author_img = scrapy.Field()
author_name = scrapy.Field()
url = scrapy.Field()
concent = scrapy.Field()
3.在pipline.py中写代码,写一个类:open_spide,close_spider,process_item
-open_spide:开启爬虫会触发
-close_spider:爬完会触发
-process_ite:每次要保存一个对象会触发
class MenusqlPipeline:
def open_spide(self,spider):
self.connection = pymysql.connect(host='127.0.0.1',user='root',password= 'xxx', database='scrapy_db',port= 3306, charset='utf8')
self.cursor = self.connection.cursor() # 获取SQL执行器(游标)
print('连接上了')
def process_item(self, item, spider): #有特殊字段一定要加反引号
sql = "insert into cnblogs(title,`desc`,author_img,author_name,url,concent) values(%s,%s,%s,%s,%s,%s)"
# 注意 params添加的顺序要和sql语句插入的顺序一致,否则会出现错位甚至插入失败的情况
params = list()
params.append(item['title'])
params.append(item['desc'])
params.append(item['author_img'])
params.append(item['author_name'])
params.append(item['url'])
params.append(item['concent'])
self.cursor.execute(sql, tuple(params)) # 4、执行SQL语句
self.connection.commit() # 5、提交到数据库
print('提交到数据库')
return item
def close_spider(self,spider):
self.cursor.close()
self.connection.close()
4.配置文件配置 -------将你在 pipline.py中自己定义的类,在setting.py中配置
ITEM_PIPELINES = {
"firstscrapy.pipelines.FirstscrapyFilePipeline": 300, # 数字越小,优先级越高
}
5.在爬虫类中调用
注意:
1.item = CnblogsItem() 定义在for内部,每次都是一个新对象,在items.py中的定义的类。
2.item['title'] = title 一定要用括号这种形式写
3.yield item 最后一定要写yield item,才能将item提交给管道,然后保存数据库
import scrapy
from myfilescrapy import pipelines
from myfilescrapy.items import CnblogsItem
from scrapy import Request
class CnblorsSpider(scrapy.Spider):
name = "cnblors" #创建爬虫时的名字
allowed_domains = ["www.cnblogs.com"] #能够访问的域
start_urls = ["https://www.cnblogs.com"] #爬取的初始地址
def parse(self, response):
article_list = response.xpath('//*[@id="post_list"]/article')
for article in article_list:
item = CnblogsItem() # 定义在for内部,每次都是一个新对象 在items.py中的定义的类
title = article.xpath('./section/div/a/text()').extract_first()
author_img = article.xpath('./section/div/p//img/@src').extract_first()
desc = article.xpath('./section/div/p/text()').extract()
'''
['\n ', '\n 〇、前言 日常开发中经常会遇到数据统计,特别是关于报表的项目。数据处理的效率和准确度当然是首要关注点。 本文主要介绍,如何通过 Parallel 来并行处理数据,并组合 ConcurrentBag 集合,来将处理效率达到高点的同时,也能确保数据的准确。 一、ConcurrentBag 简 ...\n ']
'''
real_desc = desc[0].replace('\n', '').replace(' ', '')
if real_desc:
desc = real_desc
else:
real_desc = desc[1].replace('\n', '').replace(' ', '')
desc = real_desc
author_name = article.xpath('./section/footer/a/span/text()').extract_first()
url = article.xpath('./section/div/a/@href').extract_first()
item['title'] = title
item['desc'] = desc
item['author_img'] = author_img
item['author_name'] = author_name
item['url'] = url
yield Request(url=url,callback=self.parse_deil,meta={'item':item})
# 获取下一次地址
next = 'https://www.cnblogs.com/'+response.xpath('//div[contains(@class,"pager")]/a[last()]/@href').extract_first()
yield Request(url=next,callback=self.parse)
def parse_deil(self,response):
# cnblogs_post_body
item= response.meta.get('item')
concent = str(response.xpath('//div[contains(@class,"post")]').extract_first())
item['concent'] = concent
yield item #最后一定要写yield item,才能将item提交给管道,然后保存数据库