zoukankan      html  css  js  c++  java
  • scrapy框架使用-crawlspider类,rule的使用,翻页功能,

    ###

    在Scrapy基础——Spider中。Spider基本上能做很多事情了,但是如果你想爬取一个网站的全站的话,你可能需要一个更强大的武器。
    CrawlSpider基于Spider,但是可以说是为全站爬取而生。

    ##

    生成一个crawlspider的爬虫:

    命令:scrapy genspider -t crawl spider2 "baidu.com"

    之前创建的普通爬虫的命令:scrapy genspider spider1 baidu.com,多了一个-t crawl,

    区别:

    1,首先继承的父类就是不一样的,class Spider1Spider(scrapy.Spider):     -------    class Spider2Spider(CrawlSpider):

    2,多了一个rules,这个就是定义规则的地方,

    第一个参数就是正则表达式,

    第二个callback 不是一定要的,可以没有这个参数,因为提取出的url,不需要处理

    第三个参数,在提取url的下一个页面是否需要再次按照前面的规则继续提取,

    3,parse函数不见了,这个地方不能定义parse函数,这个函数有特殊的用处,

    ####

    使用crawlspider翻页

    import scrapy
    from scrapy.linkextractors import LinkExtractor
    from scrapy.spiders import CrawlSpider, Rule
    
    
    class Spider2Spider(CrawlSpider):
        name = 'spider2'
        allowed_domains = ['17k.com']
        start_urls = ['https://www.17k.com/all/book/2_0_0_5_1_0_2_0_1.html']
    
        rules = (
            # Rule(LinkExtractor(allow=r'https://www.17k.com/book/d+.html'), callback='parse_item'),
            Rule(LinkExtractor(allow=r'https://www.17k.com/all/book/2_0_0_5_1_0_2_0_d+.html'), callback='parse_item',
                 follow=True),
        )
    
        def parse_item(self, response):
            print(response.url)
            ret = response.xpath("//table//td//span/a")
            # print(ret)
            for i in ret:
                item = {}
                # print(i.xpath('./text()').get())
                # print(i.xpath('./@href').get())
                item["title"] = i.xpath('./text()').get()
                item["href"] = "https:" + i.xpath('./@href').extract_first()
    
                # print(item)
    
                yield scrapy.Request(
                    item["href"],
                    callback=self.getDetail,
                    meta={"item": item}
                )
    
        def getDetail(self, response):
            # print(response.url)
            # print(response.meta["item"])
            item = response.meta["item"]
            item["clickNum"] = response.xpath("//td[@id='hb_week']/text()").extract_first()
            print(item)
            yield item
    
    
    if __name__ == '__main__':
        from scrapy import cmdline
    
        cmdline.execute("scrapy crawl spider2 --nolog".split())

    ####

    认识这个crawlspider方法:

    1,这个rule,是非常关键的,这是重点!!!这个规则,是把所有的翻页url拿到了,然后callback,处理每一页,follow=True这是需要往下递归的,看情况是不是需要

    2,其他的用法都是和spider类类似的,包括对管道的使用等,

    ####

    关于对rule的使用

    1,第一个参数,LinkExtractor(),就是一个提取器,里面就是你要提取的连接,

    2,第二个参数,callback,这个回调函数,就是签名提取器的每一个连接,都会循环进入这个回调函数进行处理,

    3,第三个参数,follow,这个是一个TRUE,或者FALSE,这个就是是否在提取的连接之后,继续往下提取,

    这个参数很重要,比如100页,可以帮我们一直爬取到100页,而且是去重的url,

    4,这个rules,是可以有多个规则的,但是使用的道理都是一样的,而且不同规则之后提取出来来的url,也会进行去重,这个很厉害了,好吧,

    5,另外你要知道,可以有多个回调函数的,

    6,这个rule一定要有,否则这个代码是跑不起来的,

    ###### 

    对这个链接提取器的理解,

    import scrapy
    from scrapy.linkextractors import LinkExtractor
    
    
    class Spider6Spider(scrapy.Spider):
        name = 'spider6'
        allowed_domains = ['17k.com']
        start_urls = ['https://www.17k.com/all/book/2_0_0_5_1_0_2_0_1.html']
    
        def parse(self, response):
            print(response)
            # pageurl = LinkExtractor(r'https://www.17k.com/all/book/2_0_0_5_1_0_2_0_d+.html')
            # pageurl = LinkExtractor()
            pageurl = LinkExtractor(allow=r"2_0_0_5_1_0_2_0_d")
    
            # print(pageurl.extract_links(response)) # 这是一个列表
            print(type(pageurl.extract_links(response)[0]))  # <class 'scrapy.link.Link'>
            print([i.url for i in pageurl.extract_links(response)])
    
    if __name__ == '__main__':
        from scrapy import cmdline
        cmdline.execute("scrapy crawl spider6 --nolog".split())

    ####

    可见,

    1,这个连接提取器是可以单独使用的,

    2,如果提取器里面不写正则,就是提取所有的url,这个要注意,

    3,另外pageurl.extract_links(response)这个用法,要知道,

    4,这是返回了一个列表,

    5,列表里面是一个link类型的东西,可以通过.url,.text,把内容拿出来,就可以单独使用了,这个就不用自己写了,

    其中的link_extractor既可以自己定义,也可以使用已有LinkExtractor类,主要参数为:

    allow:满足括号中“正则表达式”的值会被提取,如果为空,则全部匹配。
    deny:与这个正则表达式(或正则表达式列表)不匹配的URL一定不提取。
    allow_domains:会被提取的链接的domains。
    deny_domains:一定不会被提取链接的domains。
    restrict_xpaths:使用xpath表达式,和allow共同作用过滤链接。还有一个类似的restrict_css

    所以现在对这个提取器还是有了更进一步的认识了,

    ##
    通过这个crawlspider是可以爬取全站数据的,

    就是把这个连接提取器为空,就是提取所有的url,就可以一直爬取下去了,

    比如爬取天涯网站上面所有的邮箱,这就厉害了,

    比如爬取百度百科所有的词条,这个也是有价值的,

    ####

    所以你使用普通的spider写一个单页的爬虫,

    然后修改继承的类,增加rule就可以进行多页的爬虫,甚至是全站的爬虫,

    这就是框架牛逼的地方,

    ####

    实战阳光问政,这个有ip反爬,我正好用这个练练手,

    ###

    现在爬17k

    ###

    代码:

    import scrapy
    from scrapy.linkextractors import LinkExtractor
    from scrapy.spiders import CrawlSpider, Rule
    
    
    class Spider2Spider(CrawlSpider):
        name = 'sun'
        allowed_domains = ['17k.com']
        start_urls = ['https://www.17k.com/all/book/2_0_0_5_1_0_2_0_1.html']
    
        rules = (
            # 翻页
            Rule(LinkExtractor(allow=r'https://www.17k.com/all/book/2_0_0_5_1_0_2_0_d+.html')),
            # 详情页
            Rule(LinkExtractor(allow=r'https://www.17k.com/book/d+.html'), callback='getDetail'),
    
        )
    
        def parse_item(self, response):
            print(response.url)
    
    
        def getDetail(self, response):
            book_info = response.xpath("//p[@class='intro']/a/text()").getall()
            print(book_info)
            print("##############")
    
    
    
    if __name__ == '__main__':
        from scrapy import cmdline
    
        cmdline.execute("scrapy crawl sun --nolog".split())

    ###

    这个就是实现了自动翻页,而没有回调函数,Rule(LinkExtractor(allow=r'https://www.17k.com/all/book/2_0_0_5_1_0_2_0_d+.html')),

    ###

    ####

  • 相关阅读:
    若silverlight程序在访问时不加载或白屏怎么办?直接访问xap文件报错:404怎么办?
    iis7 发布mvc3 遇到的HTTP错误 403.14Forbidden Web 服务器被配置为不列出此目录的内容
    Windows server 2008 64bit计划任务运行使用了excel 2003 32bit .net开发组件的程序遇到的问题
    运行WeCompanySite时遇到Error creating context 'spring.root': Error thrown by a dependency of object 'System.Data.SQLite' defined in 'assembly [Spring.Data,
    javascript中创建对象,并序列化为json,通过$.ajax的提交json数据到后台方法,取值为null的问题
    c# web.config 中SessionState的配置(转载)
    第一次使用Excel2007的Microsoft Query遇到的问题及解决:别名的使用
    开博
    谁更了解用户需求
    开发人员为何应该使用 Mac OS X 兼 OS X 小史
  • 原文地址:https://www.cnblogs.com/andy0816/p/15058985.html
Copyright © 2011-2022 走看看