我用Python程序员每天写500字

Python爬虫学习(十八)Scrapy之Spiders

2018-01-20  本文已影响145人  弃用中

Python爬虫学习(十七)Scrapy命令行工具中提到的命令,我想大家应该摸索得差不多了,哈哈,还是挺有趣的吧。

本文就开始聊一聊,Scrapy中的Spiders。

Spider 类定义了如何爬取某个(或某些)网站。包括了爬取的动作(例如:是否跟进链接)以及如何从网页的内容中提取结构化数据(爬取item)。 换句话说,Spider 就是您定义爬取的动作及分析某个网页(或者是有些网页)的地方。

对于spider,爬取循环做着下面的事情:

  1. 首先生成抓取第一个URL的初始 request,request 下载完成后生成 response ,然后指定对 response 要使用的回调函数。

    通过调用 start_requests()方法(默认情况下)为 start_urls 中指定的URL生成初始的 Request以及将 parse方法作为请求的回调函数。

  2. 在回调函数中,您将解析 Response(网页)并返回带有提取的数据的 dict,Item对象, Request 对象或这些对象的可迭代容器。这些请求还将包含回调(可能是相同的),然后由 Scrapy 下载,然后由指定的回调处理它们的响应。

  3. 在回调函数中,通常使用选择器来解析页面内容(但也可以使用BeautifulSoup,lxml或您喜欢的任何解析器),并使用解析的数据生成 Item。

  4. 最后,从爬虫返回的 Item 通常将持久存储到数据或写入文件。

如果你看完上述内容是这个状态,


那么,或许我们可以用前面学到的知识解读一下:

在没有用到Scrapy这个框架的时候,我们老是自己写代码去请求网页,获得响应,然后再用正则表达式、BeautifulSoup等工具来提取我们想要的信息,最后,再把提取到的结构化的数据存到文件或则数据库中。这不就分别对应着上述内容嘛,简单吧!

Spider类中包含了一些很重要的方法和属性:

定义此爬虫名称的字符串。爬虫名称是爬虫如何由 Scrapy 定位(和实例化),因此它必须是唯一的。但是,可以生成多个相同的爬虫实例(instance),这没有任何限制。 name是spider最重要的属性,而且是必须的。

URL列表。当没有指定特定 URL 时,爬虫将从从该列表中开始抓取。因此,爬取的第一个页面将是这里列出的某个 URL。后续的 URL 将根据包含在起始 URL 中的数据连续生成。

当response没有指定回调函数时,这是Scrapy用来处理下载的response的默认方法。parse 方法负责处理response并返回所抓取的数据以及跟进的URL。Spider 对其他的Request的回调函数也有相同的要求。

当然,还有很多其他内容,这就不多说了,感兴趣的话,自己去看看文档。

我们就用这些信息写爬一下电影天堂:


地址为:http://www.ygdy8.net/html/gndy/dyzz/index.html

我们可以用昨天学到的scrapy view命令尝尝鲜,

可以看到:


原来,请求到的网页是这样的,没了那些花里胡哨的东西啦!那么,就不妨再进一步,审查元素,了解网页结构:


OK,结构已了解,现在已经是老司机的我们对这个应该是轻车熟路咯。

我们的目的是提取到每部电影的下载链接

捋一捋思路,机智的你肯定也想到了,我们需要分成两步:首先是到达每部电影的主页,然后便是提取下载链接。很好,分析的差不多,可以动手写代码了。

# -*- coding: utf-8 -*-
import scrapy


class DianyingSpider(scrapy.Spider):
    name = 'dianying'
    domain = 'http://www.ygdy8.net'
    start_urls = ['http://www.ygdy8.net/html/gndy/dyzz/index.html']

    def parse(self, response):
        for link in response.css('a.ulink::attr(href)').extract():
            # link是相对路径
            url = response.urljoin(link) # 拼接成绝对路径
            yield scrapy.Request(url, callback=self.parse_movie)
    
    def parse_movie(self, response):
        yield {
            'name':response.css('div.title_all h1 font::text').extract_first(), # 提取电影标题
            'link':response.css('td a::attr(href)').extract_first() # 提取下载地址
        }

代码写完,我们可以直接运行它,使用scrapy runspider命令即可。

结果如下:


当然,你也可以把它保存到文件中。

可这只是爬了一页的内容,最新的电影可有一百多页,怎么弄?哈哈哈,其实只要把parse函数小小的改动一下即可,要不你想想呗。

对了,之前还写过了另一个没用框架的版本,这里可以找到:https://github.com/viljw/PythonSpider

最后,我也把部分内容放到了博客中:www.viljw1557.cn,码字不易,打发点可好(羞)!

以上。

上一篇下一篇

猜你喜欢

热点阅读