码迷,mamicode.com
首页 > 编程语言 > 详细

python - scrapy 爬虫框架(创建, 持久化, 去重, 深度, cookie)

时间:2019-03-17 01:25:41      阅读:196      评论:0      收藏:0      [点我收藏+]

标签:raw   rop   page   call   存储   return   mit   ssm   ==   

## scrapy 依赖 twisted
  - twisted 是一个基于事件循环的 异步非阻塞 框架/模块

 

##  项目的创建 

1. 创建 project
    scrapy  startproject  项目名称
   
    项目名称(项目结构)
        - spiders    # 爬虫文件
            - q.py
            - w.py
        - items.py         # 持久化
        - pipelines         # 持久化
        - middlewares.py   # 中间件
        - settings.py    # 配置文件(爬虫)
    scrapy.cfg    # 配置文件(部署)

2. 创建爬虫
    cd 项目名称
   
    scrapy genspider  q  q.com
    scrapy genspider  w  w.com

3. 启动爬虫
    scrapy crawl  q --nolog   # 不查看日志
    scrapy crawl  w              # 默认查看日志

 

## pipeline 做持久化

    - pipeline 是所有爬虫公用的,如果想要给某个爬虫制定需要使用 spider 参数进行判断处理:
      if spider.name == ‘xxx‘

1. 自定义的爬虫文件中 将每次获取到的数据 传给 ScrapyDeom1Item 类方法
for item in item_list:
    href = item.xpath(.//a/@href).extract_first()
    txt = item.xpath(.//a/text()).extract_first()
    yield ScrapyDeom1Item(text=txt, href=href)

2. items 中 ScrapyDeom1Item 类方法 将需要存储的数据接收到。
class ScrapyDeom1Item(scrapy.Item):
    href = scrapy.Field()
    text = scrapy.Field()

3. settings 中定义做持久化的类( ScrapyDeom1Pipeline ) 和 定义一个文件路径
ITEM_PIPELINES = {
   scrapy_deom1.pipelines.ScrapyDeom1Pipeline: 300,
       # 文件路径                       # 优先级( 1-1000 )
}
PATH = new.log

4. 到 pipelines.py 文件中 找到 ScrapyDeom1Pipeline 类并做持久化
from scrapy.exceptions import DropItem
class ScrapyDeom1Pipeline(object):

    def __init__(self, path):  # 初始化定义文件操作 和 文件要保存的路径
        self.f = None
        self.path = path

    @classmethod
    def from_crawler(cls, crawler):
        """
        初始化的时候,用来创建 pipeline 对象
        :param crawler:
        :return:
        """
        # 去settings 寻找要保存的文件路径
        path = crawler.settings.get(PATH)
        return cls(path)

    def open_spider(self, spider):
        """
        爬虫刚启动时调用 - 此处用来做打开文件操作
        :param spider:
        :return:
        """
        self.f = open(self.path, a+)

    def process_item(self, item, spider):
        """
        爬虫执行中调用 - 此处用来做将数据写入文件 操作
        :param item:
        :param spider:
        :return:
        """
        self.f.write(item[href]+\n)
        # raise DropItem()   # 抛出异常,使后续的 pipeline 的 process_item 方法不执行
        return item    # 这个 item 是要返回给下个类的

    def close_spider(self, spider):
        """
        爬虫执行完毕后调用 - 此处用来做关闭文件操作
        :param spider: 
        :return: 
        """
        self.f.close()

 

## 去重

1. 创建一个 dupefilters.py 文件(用于做去重操作):
from scrapy.dupefilters import BaseDupeFilter
from scrapy.utils.request import request_fingerprint


class MyDupeFilter(BaseDupeFilter):

    def __init__(self):
        self.visited_fd = set()

    @classmethod
    def from_settings(cls, settings):
        return cls()

    def request_seen(self, request):
        """
        判断当前请求的URL是否存在 - 用于去重
            - 如果存在则  pass
            - 如不存在则  添加
        :param request:
        :return:
        """
        # 将当前 URL 加密成一定位数的字符
        print(request)
        fd = request_fingerprint(request=request)
        if fd in self.visited_fd:
            return True
        self.visited_fd.add(fd)

    def open(self):  # can return deferred
        """
        执行前的一些操作
        :return:
        """
        print(爬虫开始)

    def close(self, reason):  # can return a deferred
        """
        执行结束后的一些操作
        :param reason:
        :return:
        """
        print(爬虫结束)

    def log(self, request, spider):  # log that a request has been filtered
        """
        访问的每一个  URL  的日志信息
        :param request:
        :param spider:
        :return:
        """
        pass


2. settings 中注册这个类
DUPEFILTER_CLASS = scrapy_demo1.dupefilters.MyDupeFilter

3. 可以设置是否使用当前定义的去重方法
# True 表示不使用 
# False 表示使用 (默认为False)
yield Request(url=page, callback=self.parse, dont_filter=True)

 

##  限制深度查询

配置文件中(settings):
DEPTH_LIMIT = 3  # 查询深度设置为三层

 

##  Cookie

from scrapy.http.cookies import CookieJar
cookie_dict = {}
# 去对象中将cookie解析到字典
        for k, v in cookie_jar._cookies.items():
            for i, j in v.items():
                for m, n in j.items():
                    self.cookie_dict[m] = n.value

 

python - scrapy 爬虫框架(创建, 持久化, 去重, 深度, cookie)

标签:raw   rop   page   call   存储   return   mit   ssm   ==   

原文地址:https://www.cnblogs.com/chaoqi/p/10545034.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!