一、scrapy框架流程图
二、scrapy常用命令
·startproject
语法: scrapy startproject <project_name>
这个命令是scrapy最为常用的命令之一,它将会在当前目录下创建一个名为 <project_name>的项目。
·genspider
语法: scrapy genspider [-t template] <name> <domain>
在当前项目中创建spider。该方法可以使用提前定义好的模板来生成spider。您也可以自己创建spider的源码文件。
·crawl
语法: scrapy crawl <spider_name>
使用你项目中的spider进行爬取,即启动你的项目。
·shell
语法: scrapy shell [url]
以给定的URL(如果给出)或者空(没有给出URL)启动Scrapy shell。
例如,scrapy shell http://www.baidu.com将会打开百度URL,并且启动交互式命令行,可以用来做一些测试。
·fetch
语法: scrapy fetch <url>
使用Scrapy下载器(downloader)下载给定的URL,并将获取到的内容送到标准输出。简单的来说,就是打印url的html代码。
·view
语法: scrapy view <url>
在你的默认浏览器中打开给定的URL,并以Scrapy spider获取到的形式展现。 有些时候spider获取到的页面和普通用户看到的并不相同,一些动态加载的内容是看不到的, 因此该命令可以用来检查spider所获取到的页面。
三、scrapy各部分的作用
1.Items.py文件 : 定义抓取的数据变量并放到一个Item里。
class xxxxItem(scrapy.Item):
# define the fields for your item here like:
name = scrapy.Field()
wage = scrapy.Field()
firm = scrapy.Field()
requirement = scrapy.Field()
2.spider.py文件 :清洗下载返回后的response,提取response里需要的数据。提取后,通过导入Items的xxxxItem类,实例化一个新的数据Item, 把提取后的数据放入Item中,传入pipelines管道文件进行io操作。
def parse(self, response):
item = BossItem() # 实例一个item
# 通过css找到类名位job-primary下span的子标签
for info in response.css('.job-primary span'):
item['name'] = info.css('::text').extract() # 将文本文件放入item里
print(info.css('::text').extract()) # 返回item
yield item
3.pipelines.py文件 : 把spiders文件发送过来的item通过它执行一些行为,决定Item是否继续通过pipelines,或是丢弃不再处理。若通过则将数据根据需要,储存起来(文本or数据库)。
item pipelines的一些典型应用:
a)清理HTML数据
b)验证爬取的数据(检查item包含某些字段)
c)查重(并丢弃)
Item pipelines有以下函数:
-
process_item(item, spider)
该方法必需实现,定义的Item pipeline会默认调用该方法对Item进行处理,它返回Item类型的值或者抛出DropItem异常 -
open_spider(spider)
该方法非必需,在Spider开启时被调用,主要做一些初始化操作,如连接数据库等 -
close_spider(spider)
该方法非必需,在Spider关闭时被调用,主要做一些如关闭数据库连接等收尾性质的工作 -
from_crawler(cls,crawler)
该方法非必需,Spider启用时调用,早于open_spider()方法,是一个类方法,用@classmethod标识,它与__init__函有关,这里不详解(一般我们不对它进行修改)
以下实例来自官网(https://doc.scrapy.org/en/latest/topics/item-pipeline.html)
from scrapy.exceptions import DropItem
class PricePipeline(object):
vat_factor = 1.15
def process_item(self, item, spider):
if item['price']:
if item['price_excludes_vat']:
item['price'] = item['price'] * self.vat_factor
return item
else:
raise DropItem("Missing price in {}".format(item))
首先定义了一个PricePipeline类
定义了增值税税率因子为1.15
主函数process_item方法实现了如下功能:判断Item中的price字段,如没计算增值税,则乘以1.15,并返回Item,否则直接抛弃
总结:该方法要么return item给后边的管道处理,要么抛出异常
from scrapy.exceptions import DropItem
class DuplicatesPipeline(object):
def __init__(self):
self.ids_seen = set()
def process_item(self, item, spider):
if item['id'] in self.ids_seen:
raise DropItem("Duplicate item found: {}".format(item))
else:
self.ids_seen.add(item['id'])
return item
首先定义了一个DuplicatesPipeline类
这里比上面多了一个初始化函数__init__,set() 通过集合实现去重
主函数process_item方法首先判断item数据中的id是否重复,重复的就将其抛弃,否则就增加到id,然后传给下个管道
import json
class JsonWriterPipeline(object):
def open_spider(self, spider):
self.file = open('items.json', 'w')
def close_spider(self, spider):
self.file.close()
def process_item(self, item, spider):
line = json.dumps(dict(item)) + "\n"
self.file.write(line)
return item
首先我们定义了一个JsonWritePipeline类
定义了三个函数:
first:open_spider()在Spider开启时启用作用很简单即打开文件,准备写入数据
second:close_spider()在Spider关闭时启用作用也很简单即关闭文件
third(主要):process_items()作用如下首先将item转换为字典类型,在用json.dumps()序列化为json字符串格式,再写入文件,最后返回修改的item给下一个管道
import pymongo
class MongoPipeline(object):
collection_name = 'scrapy_items'
def __init__(self, mongo_uri, mongo_db):
self.mongo_uri = mongo_uri
self.mongo_db = mongo_db
@classmethod
def from_crawler(cls, crawler):
return cls(
mongo_uri=crawler.settings.get('MONGO_URI'),
mongo_db=crawler.settings.get('MONGO_DATABASE', 'items')
)
def open_spider(self, spider):
self.client = pymongo.MongoClient(self.mongo_uri)
self.db = self.client[self.mongo_db]
def close_spider(self, spider):
self.client.close()
def process_item(self, item, spider):
self.db[self.collection_name].insert_one(dict(item))
return item
首先我们定义了一个MongoPipeline类
这里我们修改了初始化函数__init__,给出了存储到Mongodb的链接地址和数据库名称所以更改了from_crawler()工厂函数函数(生产它的对象),这里指定了链接地址和数据表名称
最后我们定义了三个函数:
first:open_spider()在Spider开启时启用作用是打开mongodb数据库
second:close_spider()在Spider关闭时启用作用是关闭数据库
third:process_items()作用如下在数据库中插入item
参考链接https://www.cnblogs.com/cnkai/p/7396283.html