关于Scrapy crawlspider rules的规则——翻页

最近在学习爬虫,对于crawlspider rules的运行机制有点疑问,于是自己研究了一下,总结出以下几点:

1、rules里的Rule规则运行是有顺序的,按照由上往下执行;

2、request url的获取是Rule定位到的容器里,所有a标签里的href链接,比如用xpath定位

rules = (
        Rule(LinkExtractor(restrict_xpaths=("//div/ul")),callback='parse_item'),

    )

则在ul容器下的所有a标签的链接全都会被获取到,并且侍自动发送请求,不用自己手动发送请求;

3、响应页面是Rule请求的链接的页面内容,也就是你定位容器ul里的a标签的链接,然后你用鼠标点击该链接所看到的页面内容,在callback函数里提取数据也是在这个页面里提取,parse_item(self,response),这个函数的response对象就是这个页面内容,千万不要搞错对象了;

4、follow,这个参数开始把我搞得有点晕,follow就是跟进的意思,如果follow=True,那么,在你获取到的响应页面里,所以符合Rule规则的href链接都会被获取到,而且它还会自动跟进,进入到获取到的链接响应页面,在该页面又一次匹配Rule规则,看看有没有符合的,如果有又继续跟进,一直到匹配不到规则为止。举个例子:

rules = (
        Rule(LinkExtractor(restrict_xpaths=("//div/ul")),follow=True),

    )

那么首先,该规则会获取当前页面符合Rule规则的所有a链接,当前页面就是start_urls页面,比如获取到的链接为

<a class='dd_first ' href="http://book.dangdang.com/textbook?biaoti" target="_blank" title="教材"    nname="book-65152-9163_1-468598_2"  ddt-src="http://book.dangdang.com/textbook?biaoti">教材</a>

它会继续进入这个href链接的页面,然后继续再匹配Rule规则,看看还有没有符合的链接,就相当于你在响应页面的elements里面查找到符合规则的a标签url之后,再点击这个url,再在这个页面的elements里查找还有没有符合Rule规则的href链接,如此循环,直到找不到符合Rule规则为止;

5、如果Rule规则里有callback="parse_item",follow=True,那么情况就会比较复杂,你可以想像获取到一个响应页面符合Rule规则的链接,然后调用函数,在这个页面再去follow其它的目标链接,再调用函数,用xpath定位会相对好一点,如果用allow=(r'')正则表达式匹配,会相对混乱点,适当的情况下也会这样子用,但是比较少吧,可以自己测试体验一下。

6、翻页,翻页有两种情况

第一种情况(start_url的响应页面下方有翻页链接):

在rules里定义两条Rule规则,一条是获取响应页面规则,一条是获取翻页链接规则,翻页的规则跟在获取响应页面规则下面,顺序不要搞错了,如下:

  rules = (
        Rule(LinkExtractor(allow=r'/web/site0/tab5240/info\d+\.htm'), callback='parse_item'),
        Rule(LinkExtractor(allow=r'http://bxjg.circ.gov.cn/web/site0/tab5240/module14430/page\d\.htm'),follow=True),

    )

第二种情况(start_url的响应页面下方没有翻页链接,要进入a 标签链接才有翻页链接):

这种情况下,就不能在rules定义翻页规则了,因为即使定义了翻页规则,也找不到,因为rules里面的所有规则,第一次获取响应页面都是对应start_url地址的内容,在这个页面上没有符合Rule规则的,就找不到了,这里我也不多说了,直接去源码吧!

class TestSpider(CrawlSpider):
    name = 'test'
    allowed_domains = ['dangdang.com']
    start_urls = ['http://book.dangdang.com/']
    rules = (
        Rule(LinkExtractor(restrict_xpaths=("//div[@class='conflq_body']/div[@name='m403752_pid5438_t10274']//div/dl[@ddt-area='5358']/dd")), callback='parse_item'),

    )

    def parse_item(self, response):
        item={}
        item['cate_0']=''
        item['cate_1'] = ''
        item['cate_2'] = ''
        item['cate_3'] = ''
        breadcrum=response.xpath("//div[@class='crumbs_fb_left']/div[@class='select_frame']/a[@name='breadcrumb-category']/text()").getall()
        for i in range(len(breadcrum)):
            item['cate_{}'.format(i)]=breadcrum[i]
        book_li=response.xpath("//div[@id='search_nature_rg']/ul/li")
        for li in book_li:
            item['book_title']=li.xpath(".//p[@class='name']/a/@title").get()
            item['book_price']=li.xpath(".//p[@class='price']/span/text()").get()
            item['book_url']=li.xpath(".//p[@class='name']/a/@href").get()
            book_search=li.xpath(".//p[@class='search_book_author']/span")
            item['book_author']=book_search[0].xpath(".//a/@title").get()
            item['public_date']=book_search[1].xpath(".//text()").get()
            item['public_date']=re.sub("/",'',item['public_date']) if item['public_date'] else None
            item['public_company']=book_search[2].xpath(".//a/@title").get()

            yield item

        next_page_url=response.xpath("//div[@class='paging']//li[@class='next']/a/@href").get()
        next_page="http://category.dangdang.com"+next_page_url
        yield scrapy.Request(next_page,callback=self.parse_item)

这种情况下的翻页要在函数里面进行,在parse_item()函数的最后三行,是翻页语句!自己可以测试一下,我也不知道rules规则能不能有其它方法可以做到,反正我现在没发现,如果有朋友知道的可以告诉一下!

以上是我自己的个人观点,如有错漏烦请指出!

 

  • 6
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值