scrapy框架使用-翻页&实战

###

scrapy框架使用-翻页&实战

 

 

 ####

之前使用request直接是访问url就可以了,但是现在使用scrapy需要构造一个request对象传递给调度器,所以怎么处理?

scrapy框架使用-翻页&实战

 

 

 ###

scrapy框架使用-翻页&实战

 

 

 ###

爬取腾讯招聘,

第一步,创建一个爬虫,可以到spiders文件夹下面进行新建爬虫

scrapy genspider hr tencent.com

####

爬虫:

import scrapy
import logging

logger = logging.getLogger(__name__)

class HrSpider(scrapy.Spider):
    name = 'hr'
    allowed_domains = ['sh.cn']
    start_urls = ['http://www.ypxx.edu.sh.cn/dysl.htm']

    def parse(self, response):
        li_list = response.xpath('//div[@class = "list_main_content"]//li')
        # print("li_list", li_list)

        for li in li_list:
            item = {}
            item["subject"] = li.xpath('./a/text()').extract_first()
            item["time"] = li.xpath('./span/text()').extract_first()
            # print("item", item)
            yield item

        next_url = response.xpath('//a[@class = "Next"][1]/@href').extract_first()
        if next_url:
            next_url = "http://www.ypxx.edu.sh.cn/" + next_url
            # 把next_url的地址通过回调函数callback交给parse方法处理
            yield scrapy.Request(next_url, callback=self.parse)

注意下一页的处理方式,callback是自己,因为和上一次的处理方式是一样的,这里很像一个递归,什么时候结束,就是next_url没有的时候,就结束了,

如果处理方式不一样,就要另外定义一个函数,单独处理了,

这里的请求都没有设置useragent,没有header, 那这个怎么设置?

在setting里面:

USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.164 Safari/537.36'

####

pipeline,

from pymongo import MongoClient

myclient = MongoClient()
mycollection = myclient["tencent"]["hr"]


class MyspiderPipeline:
    def process_item(self, item, spider):
        # item["hello"] = "world"
        mycollection.insert(item)
        print(item)
        return item

中间使用了MongoDB存储数据,

###

上面讲了三个事情

1,useragent设置

2,yield一个request对象,实现翻页,callback,

注意,构造request对象的时候,我们只是使用了url,callback,还可以有method(get或者post),headers,body,cookies,meta,dont_filter=false

注意cookies和headers要分开,不能放到一起,这样是不行的,

meta很重要,在不同的解析函数之间,请求数据的,比如一个列表页,一个详情页,怎么把列表页的数据,传递到详情页呢?(因为有什么详情页数据不完整,我们需要把列表页和详情页的数据进行组装到一起,)具体实现如下:

 scrapy框架使用-翻页&实战

 

dont_filter,是否要过滤,如果一个url的请求内容经常会变化,我们就需要把这url再次去请求,设置为TRUE,可以反复去请求这个url,

####

 

 阳光政务爬虫实战

scrapy框架使用-翻页&实战

 

scrapy框架使用-翻页&实战

 

#######

阳光政务爬虫的关键点

1,yield request,请求下一页

2,使用了meta,爬取详情页

scrapy框架使用-翻页&实战

注意,最后的parse_detail,最后的需要yield item,把这个传递到pipeline里面去

注意,extract_first(),还有extract()这两个的区别,一个是取第一个,一个是取下面的所有,

注意,列表推导式的使用,这个很好用,

注意,scrapy里面有twisted异步框架, 所以,进行parse的时候,parse_detail的时候可能同时再处理,不是先后的顺序,

3,使用item对象,定义字段

scrapy框架使用-翻页&实战

scrapy框架使用-翻页&实战

4,获取到的内容,处理的技巧

scrapy框架使用-翻页&实战

 

 

scrapy框架使用-翻页&实战

 

注意这个地方的写法和技巧,

注意,单独写了一个函数来调用函数处理content,

注意,先把不要的字符,替换成空,然后把空再去掉,

注意,使用了正则表达式,这个还需要研究研究

5,存储到MongoDB中,需要把item 对象转换成为字典

 使用dict强制转换就可以了

#####

 debug

当你爬的域名,不是自己定义的域名的时候,就会报错这个,被过滤掉了,

scrapy框架使用-翻页&实战

 

如果你设置了LOG_LEVEL为WARNing可能就看不到这个debug日志了,

scrapy框架使用-翻页&实战

 

 ####

scrapy框架使用-翻页&实战

 

 通过这个可以调试,

如果你安装了ipython,就是进入ipython,

和requests模块的使用是一样的,

还可以使用这个调试xpath,比如,response.xpath("xxx").extract()

####

settings.py框架都有,Django也有,flask也可以自己创建,可以存放一些公共变量,

 scrapy框架使用-翻页&实战

 

命名的时候使用全大写的命名

一些公共的变量,可以说必须要放到配置文件,这样改一个地方就可以了,否则全项目找,很不好,

 scrapy框架使用-翻页&实战

 

如果你在spider中使用settings有两个方法

1导入

2spider自带了一个settings方法可以使用

scrapy框架使用-翻页&实战

 

如果你在pipeline中使用settings怎么用呢?

也是两个方法

1,导入

2,使用spider.settings

scrapy框架使用-翻页&实战

 

 

 #####

scrapy框架使用-翻页&实战

 

像数据库的连接可以放到open_spider,好处就是只连接一次,

 scrapy框架使用-翻页&实战

 

之前连接数据库是写在类外边的,也可以,

scrapy框架使用-翻页&实战

 

####

scrapy框架使用-翻页&实战

 

这个能写出来,其他的都是渣渣了,

爬一本书的,大分类,小分类,名字,作者,出版社,价格(在详情页)

 scrapy框架使用-翻页&实战

 

分析:

首先按照大分类分组,然后按照小分类分组,然后就是获取到列表,然后获取书的信息包括列表页和详情页的每一个图书的信息,

所以程序的入口是获取大分类和小分类,然后后面的都是一样的了,

关键是第一步获取到了怎么做?

scrapy框架使用-翻页&实战

使用deepcopy,可以不被影响,不会重复内容,

 scrapy框架使用-翻页&实战

 

 

 要判断我们想要的内容是否在html里面,不在的话,就要请求另外的地址了,

#####

 scrapy框架使用-翻页&实战

这样写出来的列表页的图片是获取不到的,有的是src,有的是src2,

怎么处理?

scrapy框架使用-翻页&实战

 

 但是内容爬取的有重复是为什么?

scrapy框架使用-翻页&实战

 

因为scrapy里面是同时操作item的,所以会有覆盖, 

可能正在获取价格,但是上面item也在操作,所以用的是同一个item ,就会有问题,

为什么使用request没有这个问题,因为request是同步的,scrapy是异步的, 

 scrapy框架使用-翻页&实战

 

使用deepcopy,

 列表页,加上翻页的问题

这个页面使用了Ajax请求,因为页面顶部的地址没有变化,但是内容变了,

scrapy框架使用-翻页&实战

 

正则提取翻页请求的这个字段,

翻页的请求url,就是改变page的数量就可以了,那什么结束加+1呢,就是看上面的那个总页数,

 scrapy框架使用-翻页&实战

 

上面的代码有一个错误,decode没有加括号

scrapy框架使用-翻页&实战

 

  

 

 

####

scrapy框架使用-翻页&实战

 

 

 ###

为什么之前没事?阳光政务平台就好的,不会重复,

因为这个地方使用for嵌套for,

####

 

###

上一篇:爬虫终 scrapy框架2 全站爬取cnblogs, scarpy请求传参, 提高爬取效率, 爬虫中间件下载中间件, 集成selenium, fake-useragent, 去重源码分析, 布隆过滤


下一篇:scrapy框架-scrapy-redis的使用