欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【爬虫】-013-Scrapy-CrawlSpider实例

程序员文章站 2022-05-06 18:47:21
...

LinkExtractor类

  • 基本概念

在爬取一个网站时,想要爬取的数据通常分布在多个页面中,每个页面包含一部分数据以及到其他页面的链接,提取链接有使用Selector和使用LinkExtractor两种方法Selector常用的有CSS SelectorXpath,在Scrapy框架中,内置了LinkExtractor类来爬取页面中的链接。

LinkExtractor类的对象作用是从网页(即Response对象)中抽取最终将会被follow链接。LinkExtractor有唯一的公共方法是 extract_links ,它接收一个Response对象,并返回一个 scrapy.link.Link 对象。Link Extractor要实例化一次并且 extract_links 方法会根据不同的response调用多次提取链接。

  • 例子

进入实验环境:

scrapy shell http://hz.ganji.com/zufang/pn2/

导入 LinkExtractor库:

from scrapy.linkextractors import LinkExtractor

创建 LinkExtractor对象,设置正则规则,从当前页面中寻找目标链接:

le = LinkExtractor(r'http://hz.ganji.com/zufang/\d+x.shtml')
le.extract_links(response)

查看获取的Link对象:

print([link for link in le.extract_links(response)])

CrawlSpider实例

根据CrawlSpider运行机制,在理解类LinkExtractor类的使用方法后,接下来实操一下如何用CrawlSpider爬虫获取数据。
接着上面的例子,我们获取详情页的标题和价格信息,代码如下:

class Ganji2Spider(CrawlSpider):
    name = 'ganji2'
    allowed_domains = ['ganji.com']
    start_urls = ['http://hz.ganji.com/zufang/pn1/']

    get_links = []

    # 匹配规则,匹配正则然后给回调函数
    rules = (
        Rule(LinkExtractor(allow=r'http://hz.ganji.com/zufang/\d+x.shtml'), callback='parse_item', follow=False),
    )

    def parse_item(self, response):
        item = {}
        item['title'] = response.xpath('//p[@class="card-title"]/i/text()').get()
        item['price'] = response.xpath('//span[@class="price"]/text()').get()
        print(item)

follow机制

现在已经可以从start_urls开始获取页面中包含的详情页链接,并获取其中的标题和价格信息。那么,如何不断的获取新的页面,再爬起详情页中的数据呢?

basic spider中,我们通过parse函数中使用xpath定位下一页元素,然后将获取的链接重新请求parse函数,从而对下一页发起请求并获得响应。【爬虫】-011-Scrapy-获取下级页面的链接

CrawlSpider中,对链接对提取使用LinkExtractor类,所以从start_urls请求后得到的response中分析下一页链接的特点,用正则表达式匹配出来。

得到的下一页链接通过请求,继续得到响应response,然后对这个response,分析其中的详情页链接,请求详情页获得响应,并使用parse_item获取响应中的数据。更详细的原理介绍可以看这里

好了,如此可以更新我们的CrawlSpider爬虫。

class Ganji2Spider(CrawlSpider):
    name = 'ganji2'
    allowed_domains = ['ganji.com']
    start_urls = ['http://hz.ganji.com/zufang/pn1/']

    # 获取的链接列表
    get_links = []

    # 匹配规则,匹配正则然后给回调函数
    rules = (
        Rule(LinkExtractor(allow=r'http://hz.ganji.com/zufang/\d+x.shtml'), callback='parse_item', follow=False),
        # 下一页链接的正则规则,持续跟进,不断发起请求
        Rule(LinkExtractor(allow=r'http://hz.ganji.com/zufang/pn\d/')),
    )

    def parse_item(self, response):
        item = {}
        # 请求下一页得到的响应中的详情页链接,将返回的响应装入列表
        self.get_links.append(response)
        # 查看响应的链接地址,通过计算列表长度来计数
        print(response.url, len(self.get_links))

        print('*' * 10)
        item['title'] = response.xpath('//p[@class="card-title"]/i/text()').get()
        item['price'] = response.xpath('//span[@class="price"]/text()').get()
        print(item)

转载于:https://www.jianshu.com/p/b7b2ecaf14e5