爬虫scrapy框架学习(二)

五、爬取苏宁易购下所有图书信息案例

5.1先利用scrapy框架创建一个爬虫项目,再创建sn_book_spider爬虫

 

5.2在sn_book_spider.py中构造请求,提取数据:

  

  

 

5.3案例总结:1.该案例最难的地方在于需要层层传递参数和请求数据,

                         请求顺序是分类-》列表-》详情,

                      2.而在运行时会遇到数据重复的问题,原因是scrapy框架是异步结构,

                         所以同一时间可能会有多个请求操作同一个item字典,就会导致数据重复覆盖,

                         解决方法是每个请求传递参数时,传递深拷贝过的参数,

                         因为深拷贝会开辟一个新的内存地址来存放对象,

                         所以拷贝后的对象和拷贝前的对象相互独立,互不干扰

 

六、Scarpy中的CrawlSpider:

6.1生成crawlspider的命令:scrapy genspider –t crawl csdn “csdn.cn”

 

6.2crawlspider的使用:

        

    

 

6.3crawlspider的参数说明:

      

 

七、下载中间件

7.1使用方法:和pipeline一样,定义一个类,然后在setting.py中开启

 

7.2Downloader Middlewares默认的方法:

            process_request(self, request, spider):

            当每个request通过下载中间件时,该方法被调用。

            process_response(self, request, response, spider):

            当下载器完成http请求,传递响应给引擎的时候调用

 

7.3下载中间件的用途主要是使用多UA或者多代理,提高反爬效率:

 

八、scrapy模拟登陆

8.1模拟登陆的意义:为了爬取登陆后的页面数据

 

8.2模拟登陆的方法:

        1.直接携带cookie登陆

                a.应用场景:

                        1.cookie过期时间很长,常见于一些不规范的网站

                        2.能在cookie过期之前把搜有的数据拿到

                        3.配合其他程序使用,比如其使用selenium把登陆之后的cookie获取到保存到本地,

                           scrapy发送请求之前先读取本地cookie

 

                b.关键认知:

                        1.通过查看scrapy.Spider源码,可以知道我们定义在spider下的start_urls=[]

                           都是默认交给start_requests处理的,

                           所以我们可以重写start_requests方法来让其携带cookie请求

                        2.要使用cookie时,需要在setting.py中开启cookie

                            

 

                c.使用示例:

                        

 

        2.发送post请求:

                    a.应用场景:适用于大部分网站

 

                    b.关键认知:我们使用scrapy.FormRequest来发送Post请求,

                                        还可以使用scrapy.FormRequest.from_response来自动寻找表单登录

 

                    c.使用示例:

                            1.首先使用常规的scrapy.FormRequest函数,需要我们自己拼接参数:

                                

 

                            2.然后使用scrapy.FormRequest.from_response函数,自动寻找表单登录:

                                    

 

    

九、scrapy_redis使用

9.1意义:Scrapy_redis在scrapy的基础上实现了更多,更强大的功能,

               具体体现在:reqeust去重,爬虫持久化,和轻松实现分布式

 

9.2工作流程:scrapy_redis的工作流程如下:

            

 

 

9.3使用:我们通过阅读scrapy_redis源码和示例来学习如何使用它

        1.示例1:

                a.编写一个爬取domz网站数据的爬虫,主体逻辑如下:

 

               

 

                  b.不同的是在setting.py中加入以下配置:

 

                 

 

                  c.这样配置以后,运行该爬虫,会发现redis多出了三个键,如下:

 

                

 

                d.其中需要注意的是,redispipeline中仅仅实现了item数据存储到redis的过程,

                   我们可以新建一个pipeline(或者修改默认的ExamplePipeline),让数据存储到任意地方

 

                e.总结:上述示例通过在setting.py中配置使用了scrapy_redis的功能,

                             使得爬虫多了持久化和request去重的功能

                        

        2.源码解析:

                a.RedisPipeline代码如下:

 

                    

 

                b.RFPDupeFilter代码如下:

 

                

 

                       解析:上述源码的流程是先使用sha1加密request得到指纹

                                 然后把指纹存在redis的集合中

                                 当新来一个request时,先用同样的方式生成指纹,

                                 然后判断该指纹是否存在reids的集合中

 

 

                c.Scheduler代码如下:

 

                   

 

                    解析:上述源码的流程是先判断爬虫的持久性,

                              如果设置为不持久则会在程序退出以后情空redis中的数据

                              然后判断request是否可以入队,入队的条件有以下几种:

                                    1.dont_filter = True ,构造请求的时候,把dont_filter置为True,

                                       该url会被反复抓取(url地址对应的内容会更新的情况)

                                    2.一个全新的url地址被抓到的时候,构造request请求

                                    3.url地址在start_urls中的时候,会入队,不管之前是否请求过

 

                d.总结:由scrapy_redis的源码,我们可以看出,

                             它的工作原理是将先所有的request都存入队列中,

                             当一次请求完成后,将对应的request从队列中pop出来,

                             将pop出来的request使用sha1加密生成指纹,存入指纹集合中

                             每当有request过来的时候,程序会先用同样的方法生成指纹,

                             然后判断该指纹是否在指纹集合中,如果在则表示这个request已经被请求过了,

                             故不再让它入队,如果不在则说明这是个全新的request,让它入队

                             这样就可以实现request的去重功能

 

 

 

                    

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小陈工

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值