爬虫框架Scrapy

爬虫框架Scrapy

  • 创建项目
    • scrapy startproject 项目名称
  • 创建爬虫
    • cd 项目名称
    • scrapy genspider example example.com
scrapy结构
项目文件夹
  • 同名文件夹
    • spiders
      • init
      • 爬虫文件
    • init
    • items.py
    • middlewares.py
    • pipelines.py
    • settings.py
  • scrapy.cfg
文件作用
  • spider下的爬虫文件:

    • 爬虫文件名称
    • 访问文件约束
    • 开始的URL地址
    • 获取请求返回的数据提取后 yield返回给pipelines.py处理
  • pipelines.py

    • 可以进行接收处理保存数据
    • 注:如果有多个爬虫文件返回数据可以分开处理,一个爬虫项目包含多个爬虫
    • 需要在settings.py设置,多个pipelines.py开启多个,数字小先访问
    • ITEM_PIPELINES = {
      'myspider.pipelines.MyspiderPipeline': 300,
      'myspider.pipelines.MyspiderPipeline1': 301,
      }
  • 多个爬虫文件爬取多个网站 pipelines.py处理

    • item中添加字段标记来源,pipelines.py进行判断
    • 可以在一个class中处理,也可以在多个class中处理

    • class MyspiderPipeline(object):
      def process_item(self, item, spider):
      if xxx["from"] == "JD"
      ···
      return item
      class MyspiderPipeline1(object):
      def process_item(self, item, spider):
      if itcst["from"] == "TB"
    • 对spider进行判断 if spider.name == "xxxx"
  • pipelines.py扩展

    • 利用特性解决问题
    • 定义def open_spider(self,spider)开始时仅执行一次
    • 定义def open_spider(self,spider)关闭时仅执行一次
  • item.py

  • 预先定义爬取的字段
    • class TencentItem(scrapy.Item)
    • title = scrspy.Field()
  • 爬虫文件中导入
    • from import
  • 实例化
    • item = TencentItem()
    • item["title"] = xpath获取
    • 注:存入数据库中需要转化为字典,
  • 判断item来源,区别来源于哪个爬虫

    • if isinstance(item,TencentItem)
  • setting.py

  • 存放公共变量,数据库地址密码等
    • from import导入使用
    • spider属性settings
    • self.settings[“”]
    • self.settings.get(“”)
  • pipelines中使用
    • spider.settings[“”]
    • spider.settings.get(“”)
log文件的作用
  • scrapy中使用方法
    • setting.py中设置 LOG_LEVEL = "WARNING"
    • import loging
    • logger = logging.getLogger(__name__)
    • logger.info/warning(item)
    • item 输出内容
    • setting.py设置日志保存本地 LOG_FILE = "./log.log"
  • 无框架爬虫文件中使用
    • 定义log文件
    • import logging
    • logging.basicConfig(样式) 设置输出保存样式
    • logger = logging.getLogger()
    • __name__ =="__main__"
    • logger.info/warning(item)
    • 执行文件
    • 注:其他文件中可以导入 from log文件名 import logger
实现翻页
  • 获取下一页URL地址
  • 判断最后一页URL地址
  • yield scrapy.Request(next_url,callback=self.parse,)
  • 如果下一页处理方式不同重新定义方法
  • 注 user可以在setting.py中创建
  • 注 ()内可以携带参数(method=”“,headers,body,cookie……)
  • 参数meta 帮助在不同解析函数传递数据 ,使用场景–列表页获取一部分数据,需要进入详情页获取其他数据,列表的数据传递到获取详情页数据的函数中进行完善。
    • meta = {“item”:{“name”:”name”,”old”:”old”…..}}
    • response.meta[“item”]
    • 数据格式 {“”:”“,”“:”“,}
    • item[“”]进行添加详情页数据
  • dont_filter = False
    • 对于URL地址过滤,防止反复请求,场景:对于数据频繁更新的URL需要反复请求。
Debug的认识
  • debug开启会打印settimg中设置的东西
  • 打印中间件的内容
  • pipline
  • 打印访问的url
  • 打印爬虫的开始结束
  • 各种数据的统计
scrapy shell
  • scrapy shell +url地址 进入交互式终端
  • 查看scrapy可用对象
  • 查看方法用法response.body ·····查看当前响应
Crawl-spider
  • 一般应用于结构简单爬虫,实现自动翻页
  • scrapy startproject 项目名称
  • cd 项目名称
  • scrapy genspider -t crawl 爬虫名称 域名限定
  • 类继承自crawlspider
    • 爬虫名
    • 域名限定
    • start_url
    • rules 提取数据规则
    • 默认生成一个函数,parse函数有特殊定义不能更改
  • rules = (
    #LinkExtractor 连接提取器,提取url地址
    #callback 提取出来的url地址的response会交给callback处理
    #follow 当前url地址的响应是够重新进过rules来提取url地址,
    Rule(LinkExtractor(allow=r'/web/site0/tab5240/info\d+\.htm'), callback='parse_item'),
    Rule(LinkExtractor(allow=r'/web/site0/tab5240/module14430/page\d+\.htm'),follow=True),
    )

  • 局限:规则之间的参数不能传递,适用一级结构翻页,直接获取二级结构内容

  • 如果要获取一级结构内容,再获取二级结构内容,rules中翻页callback函数获取一级结构内容,函数中提取二级结构URL,yield发送请求构造函数获取
下载中间件
  • middlewares.py
  • 每次请求时会经过下载中间件
  • setting中开启
  • 文件中定义一个中间件类
  • def process_request(self,request,spider)
  • 可以在数据下载前进行设置处理
  • 下载中间件的应用
    • 添加自定义useragent
    • 添加代理
    • 检查代理或者useragent是否可用
scrapy模拟登陆
  • 获取cookie,爬取登陆后的页面
  • 直接携带cookie登陆
  • post请求登陆(默认携带上一次访问的cookie)
  • 配合selenium,发送请求前提取本地cookie
  • start—url是登陆后的URL地址需要重写start_request方法
  • 开启COOKIES_DEBUG=Ture 查看cookies传递的过程
  • def start_request(self)
    cookies = ·····
    cookies = {i.split("=")[0]:i.split("=")[1] for i in cookies.split("; ")}#字典推倒式
    yield scrapy.Request(
    start_url,
    callback= ···,
    cookies = cookies#注headers不起作用
    )

  • data 数据在加载页面中

  • def parse(self,response)
    构造请求数据
    post_data = dict(
    xxxx=xxxx
    )#字典形式
    yield scrapy.Formrequest(
    登陆地址,
    数据,
    callback=函数
    )
  • 可以在登陆后的页面保存HTML查看数据,是否有用户名密码等

  • 用户登陆的form表单有action地址直接输入用户名密码到服务

  • def parse(self,response)
    yield scrapy.FormRequest.from_response(
    response,#自动寻找action地址
    formdata={},
    callback = ····
    )
Scrapy_Redis
  • scrapy流程
  • 引擎–>调度器获取request对象,存放URL—>下载器发送请求获取数据—>spider爬虫,提取数据,URL,构造request对象—>提取的数据发送给管道/URL构造request发送给引擎发送给调度器

  • 实现多个scrapy下载一个项目

    • 多个scrapy把request请求存入Redis数据库,从数据库中获取request对象
  • Redis去除重复原理

    • 每个request对象会生成一个唯一指纹,存入前通过指纹对比避免重复,Redis中存两个数据-待爬数据和爬取过的数据的指纹。
  • 从GitHub下载源码

  • 文件作用
  • domz.py
    • 继承自crowspider爬虫,自动抓取网页
    • 名称
    • 限定
    • 初始URL
    • 抓取URL规则
    • 函数
  • pipelines

    • item添加键
  • setting文件

    • DUPEFILTER_CLASS去重类
    • SCHEDULER调度器类
    • SCHEDULER_PERSIST持久化,表示程序结束后内容依然会保持
    • ITEM_PIPELINES
    • REDIS_URL = “redis://127.0.0.1:6379”
  • redis 存储的内容

    • 爬虫名:request —- 存储待爬取的对象,对象序列化存入Redis,反序列化重新转化为对象
    • 爬虫名: items —- 列表,item内容,通过pipeline保存
    • 爬虫名:dupefilter —- 集合,存放抓取过的request对象的指纹
  • 源码分析

  • pipeline处理数据—判断对象是否存在—存在返回true—hashsha1生成指纹加密返回—实现去重
  • 入队问题
  • 读scrapy_redis代码
  • 源码中redis_pipline 经过处理序列化item转化成字符串,放入键中存入Redis
  • 源码中dumpfiler 经过处理request对象,把给定的request对象生成指纹(hashlib.sha1()),注计算指纹不带cookie,headers,不然会导致同样的URL地址生成的指纹不同,重复访问。
    • 去重
    • 1f = hashlib.sha1() f.update("xxxx"encoding()) 生成指纹
    • 2生成指纹放入Redis中实现去重,如果request对象指纹存在返回0,为true,表示之前抓取过
  • 源码中scheduler调度器,对是否持久化进行控制,清空待爬对象,清空指纹
  • request对象入队问题
    • dont_filter过滤+判断指纹是否存在
    • 语句if not…and…
    • 条件成立不入对
    • dont_filter false (结果ture) + 指纹存在 true -----return true 不入
    • dont_filter false (结果true) + 指纹不存在 false -----return false 入队
    • dont_filter true (结果false) 指纹是否存在 ------ return false 入队
    • url地址在startURL地址中时候会入队 dont_filter = true
代码练习中发现的问题

pass

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值